@bangdao-ai/acw-tools 1.13.2 → 1.13.4
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/dist/claudeCodeParser.js +1 -1
- package/dist/cursorConversationParser.js +1 -1
- package/dist/index.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/package.json +1 -1
- package/dist/postinstall.js +1 -1
- package/index.js +49 -39
- package/package.json +3 -2
- package/workspaceGitUtils.js +161 -0
package/dist/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ACW工具集",
|
|
3
3
|
"description": "ACW平台工具集:智能下载规则/技能到项目、上传技能到Skills广场、搜索技能、检查技能更新、上传/下载/检索个人知识库",
|
|
4
|
-
"version": "1.13.
|
|
4
|
+
"version": "1.13.3",
|
|
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/dist/package.json
CHANGED
package/dist/postinstall.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
function _0x2ba9(_0x15a32e,_0x55e92a){_0x15a32e=_0x15a32e-0x1e2;const _0x1c63b9=_0x1c63();let _0x2ba9b7=_0x1c63b9[_0x15a32e];return _0x2ba9b7;}const _0x3a6d04=_0x2ba9;(function(_0x2787b6,_0x123cfd){const _0xe9499e=_0x2ba9,_0x41c4cb=_0x2787b6();while(!![]){try{const _0x4214fe=-parseInt(_0xe9499e(0x22b))/0x1+-parseInt(_0xe9499e(0x21f))/0x2*(-parseInt(_0xe9499e(0x233))/0x3)+-parseInt(_0xe9499e(0x220))/0x4*(parseInt(_0xe9499e(0x232))/0x5)+-parseInt(_0xe9499e(0x1ed))/0x6+parseInt(_0xe9499e(0x1ec))/0x7+-parseInt(_0xe9499e(0x1f5))/0x8+parseInt(_0xe9499e(0x240))/0x9;if(_0x4214fe===_0x123cfd)break;else _0x41c4cb['push'](_0x41c4cb['shift']());}catch(_0x140437){_0x41c4cb['push'](_0x41c4cb['shift']());}}}(_0x1c63,0x77433));import _0xbfa463 from'fs';import _0xc29181 from'path';import{fileURLToPath as _0x2d3c47}from'url';import{execSync as _0x373f19}from'child_process';import _0x103685 from'https';import _0x2e7144 from'http';import _0x206fcd from'zlib';var C=_0x3a6d04(0x1eb),L='https://bd-acw.oss-cn-beijing.aliyuncs.com/prebuilds/better-sqlite3',F={0x12:'108',0x13:'111',0x14:'115',0x15:'120',0x16:_0x3a6d04(0x222),0x17:'131',0x18:_0x3a6d04(0x22a),0x19:_0x3a6d04(0x22a)},$=[_0x3a6d04(0x23b),_0x3a6d04(0x222),_0x3a6d04(0x1ea),_0x3a6d04(0x22a)],I=parseInt(process['version'][_0x3a6d04(0x217)](0x1)['split']('.')[0x0],0xa),T=((()=>{let _0x3bd85d=process['version']['slice'](0x1)['split']('.');return parseInt(_0x3bd85d[0x1]||'0',0xa);})());function x(){return I>0x16||I===0x16&&T>=0x5;}function P(){const _0x286ee4=_0x3a6d04;console[_0x286ee4(0x245)](''),console[_0x286ee4(0x245)]('[提示]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console[_0x286ee4(0x245)]('[提示]\x20【本包为什么要动\x20SQLite】需要读取\x20Cursor\x20本地的\x20state.vscdb(对话与\x20composer\x20数据)。'),console['log']('[提示]\x20【推荐环境】请使用\x20Node.js\x2022.5\x20及以上(LTS\x2022\x20的最新小版本即可)。'),console[_0x286ee4(0x245)]('[提示]\x20\x20\x20该版本起\x20Node\x20内置「node:sqlite」,安装时无需\x20better-sqlite3,Windows\x20上可避免出现「模块编译失败」。'),console[_0x286ee4(0x245)]('[提示]\x20【你当前的情况】当前为\x20'+process[_0x286ee4(0x1e7)]+',未检测到可用的内置\x20node:sqlite(或运行时被禁用),因此走可选依赖\x20better-sqlite3。'),console[_0x286ee4(0x245)](_0x286ee4(0x205)),console[_0x286ee4(0x245)](_0x286ee4(0x241)),console['log'](_0x286ee4(0x224)),console[_0x286ee4(0x245)](_0x286ee4(0x244)),console[_0x286ee4(0x245)](_0x286ee4(0x1f6)),console[_0x286ee4(0x245)]('[提示]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console['log']('');}function y(){const _0x2b7b58=_0x3a6d04;console[_0x2b7b58(0x23d)](''),console['error']('──────────\x20给用户的说明(安装失败)──────────'),console['error'](_0x2b7b58(0x1e9)),console['error'](_0x2b7b58(0x1ee)),console[_0x2b7b58(0x23d)]('建议:将运行「npx\x20@bangdao-ai/acw-tools」的\x20Node\x20升级到\x2022.5\x20及以上,本包将改用内置\x20SQLite,一般不再需要编译。'),console[_0x2b7b58(0x23d)](_0x2b7b58(0x1f2)),console['error'](_0x2b7b58(0x1fd));}function _0x1c63(){const _0x2a82d9=['137','791430meefSa','MODULE_NOT_FOUND','inherit','string',',npm\x20包根=','includes','warn','170BndBJI','3rYsEpZ','[结论]\x20报错形态不像典型原生模块加载问题,未自动执行\x20OSS\x20/\x20rebuild,请根据完整堆栈排查。','[INFO]\x20当前\x20Node\x20','-node-v','[INFO]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━','[提示]\x20当前通过\x20better-sqlite3\x20完成检查。若希望免去原生依赖,可将\x20Node\x20升级到\x2022.5\x20及以上。','length','better-sqlite3','115','modules','error','trim','package.json','11631087PxbRLA','[提示]\x20\x20\x20·\x20Windows:未安装\x20Visual\x20Studio\x20Build\x20Tools(缺\x20cl.exe),node-gyp\x20无法编译;','\x20满足「内置\x20SQLite」路径:对话抓取不依赖\x20better-sqlite3,Windows\x20上无需\x20VS\x20Build\x20Tools\x20即可避免「模块编译失败」。','npm\x20rebuild\x20better-sqlite3\x20--foreground-scripts','[提示]\x20\x20\x20·\x20公司网络拦截导致预编译包下载失败,被迫本地编译但本机无工具链。','log','startsWith','[原因]\x20当前\x20ABI\x20','node_modules','.tar.gz','concat','[步骤]\x20执行自动\x20npm\x20rebuild\x20better-sqlite3(本机源码编译)','[提示]\x20当前\x20','[WARN]\x20无法确定\x20npm\x20包根目录,跳过\x20npm\x20rebuild','close','[WARN]\x20预编译包安装后测试失败:\x20','[ERROR]\x20better-sqlite3\x20模块加载失败,安装中止','replace','win32','Request\x20timeout','[INFO]\x20尝试从\x20OSS\x20下载预编译包:\x20','[OK]\x20已检测到\x20Node\x20内置\x20node:sqlite,安装检查通过。','cwd','then','[提示]\x20','version','acwInstallNote','本步骤失败,几乎总是「可选依赖\x20better-sqlite3」的原生模块无法在您当前环境加载或编译。','131','12.4.1','4966101xdtuYU','1300008wdXqWI','根因:它需要与本机\x20Node\x20版本匹配的\x20C++\x20二进制;Windows\x20上缺\x20VS\x20Build\x20Tools\x20时极易报错。','[OK]\x20better-sqlite3\x20修复成功(OSS\x20预编译)','说明:\x20已尝试\x20OSS\x20预编译与\x20npm\x20rebuild。仍失败时:务必把运行\x20npx\x20的\x20Node\x20升到\x2022.5+(内置\x20SQLite,从根上避免本问题)。其余检查:','我的\x20ACW\x20MCP\x20安装失败(better-sqlite3\x20/\x20原生模块),错误:','package.json\x20中\x20engines\x20为\x20node>=20;要免编译、少踩坑,请以\x2022.5+\x20为准。','existsSync','end','3748712pWqgzt','[提示]\x20【解决办法优先级】①\x20将运行\x20npx\x20的\x20Node\x20升级到\x2022.5+(最省事);②\x20安装对应系统的\x20C++\x20编译环境后再装本包;③\x20确保\x20Cursor\x20/\x20终端使用同一份\x20Node,避免\x20ABI\x20混用。','statusCode','\x20\x201)\x20终端执行\x20node\x20-v\x20与\x20Cursor\x20调起\x20MCP\x20用的是否为同一\x20Node;','join','[ERROR]\x20postinstall\x20脚本执行出错:','\x20|\x20Node\x20','parse','────────────────────────────────────────────','unknown','location','dlopen','[原因]\x20首次加载失败(动态\x20import):\x20','test','utf8','],不会下载预编译包(避免错配二进制)。将尝试本机\x20npm\x20rebuild。','[提示]\x20【为什么会编译失败】better-sqlite3\x20含\x20C++\x20扩展(.node\x20文件)。常见原因:','env','catch','mkdirSync','。优先将\x20Node\x20升到\x2022.5+。否则\x20xcode-select\x20--install\x20后\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools\x20重装。','basename','push','pipe',':memory:','[OK]\x20安装完成','\x20(ABI\x20','\x20\x202)\x20若必须留在旧\x20Node:安装\x20C++\x20工具链后在包根目录执行\x20npm\x20rebuild\x20better-sqlite3\x20--foreground-scripts;','invalid\x20ELF',')无对应\x20OSS\x20预编译包,跳过\x20OSS,将尝试本机编译',')\x20|\x20','timeout','better-sqlite3-v','headers','slice','[WARN]\x20npm\x20rebuild\x20未成功:\x20','[步骤]\x20npm\x20rebuild:\x20成功','━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━','[INFO]\x20(需本机已有\x20C++\x20构建环境;Windows\x20为\x20VS\x20Build\x20Tools,macOS\x20为\x20Xcode\x20CLT,Linux\x20为\x20build-essential)','toFixed','platform','复制以下提示词发送给\x20Cursor,让\x20AI\x20帮你修复:','72796PPOEYk','8588fxiwsm','[环境]\x20Node=','127','stdout','[提示]\x20\x20\x20·\x20任意系统:执行\x20npx\x20的\x20Node\x20版本与当初编译该模块的\x20Node\x20ABI\x20不一致(报\x20NODE_MODULE_VERSION\x20/\x20was\x20compiled\x20against);','dirname','default','toString','message','https'];_0x1c63=function(){return _0x2a82d9;};return _0x1c63();}function b(){const _0x10e18e=_0x3a6d04;let _0x555eae=parseInt(process[_0x10e18e(0x1e7)][_0x10e18e(0x217)](0x1)['split']('.')[0x0],0xa);return F[_0x555eae]||process['versions'][_0x10e18e(0x23c)];}function E(){const _0x2d30d7=_0x3a6d04;let _0x3afec6=C,_0x5cc354=b(),_0x425eba=process[_0x2d30d7(0x21d)],_0x48d62d=process['arch'];return _0x2d30d7(0x215)+_0x3afec6+_0x2d30d7(0x236)+_0x5cc354+'-'+_0x425eba+'-'+_0x48d62d+_0x2d30d7(0x249);}function v(_0x3ce993){return new Promise((_0x44e659,_0x1c2b43)=>{const _0x4c1fb6=_0x2ba9;let _0x35f61c=(_0x3ce993[_0x4c1fb6(0x246)](_0x4c1fb6(0x229))?_0x103685:_0x2e7144)['get'](_0x3ce993,{'timeout':0x7530},_0x26583a=>{const _0x44d42c=_0x4c1fb6;if(_0x26583a[_0x44d42c(0x1f7)]===0x12d||_0x26583a['statusCode']===0x12e){v(_0x26583a[_0x44d42c(0x216)][_0x44d42c(0x1ff)])[_0x44d42c(0x1e5)](_0x44e659)[_0x44d42c(0x207)](_0x1c2b43);return;}if(_0x26583a['statusCode']!==0xc8){_0x1c2b43(new Error('HTTP\x20'+_0x26583a['statusCode']));return;}let _0x1722a9=[];_0x26583a['on']('data',_0x2583d7=>_0x1722a9['push'](_0x2583d7)),_0x26583a['on'](_0x44d42c(0x1f4),()=>_0x44e659(Buffer[_0x44d42c(0x24a)](_0x1722a9))),_0x26583a['on']('error',_0x1c2b43);});_0x35f61c['on']('error',_0x1c2b43),_0x35f61c['on'](_0x4c1fb6(0x214),()=>{const _0x55e9d0=_0x4c1fb6;_0x35f61c['destroy'](),_0x1c2b43(new Error(_0x55e9d0(0x253)));});});}async function D(_0x2956fa,_0x199655){const _0x5b5afa=_0x3a6d04;let _0x507154=_0x206fcd['gunzipSync'](_0x2956fa),_0x5cc2db=0x200,_0x50ff50=0x0;for(;_0x50ff50<_0x507154[_0x5b5afa(0x239)]-_0x5cc2db;){let _0xc8a36b=_0x507154[_0x5b5afa(0x217)](_0x50ff50,_0x50ff50+_0x5cc2db);if(_0xc8a36b[0x0]===0x0)break;let _0x4907ae=_0xc8a36b['slice'](0x0,0x64)[_0x5b5afa(0x227)]('utf8')['replace'](/\0/g,'')[_0x5b5afa(0x23e)](),_0x5a60d8=_0xc8a36b['slice'](0x7c,0x88)[_0x5b5afa(0x227)]('utf8')[_0x5b5afa(0x251)](/\0/g,'')['trim'](),_0x2a4d5c=parseInt(_0x5a60d8,0x8)||0x0,_0x29f28c=String['fromCharCode'](_0xc8a36b[0x9c]);if(_0x50ff50+=_0x5cc2db,_0x4907ae&&_0x29f28c==='0'||_0x29f28c==='\x00'){let _0x132294=_0x507154['slice'](_0x50ff50,_0x50ff50+_0x2a4d5c),_0x136999=_0xc29181[_0x5b5afa(0x1f9)](_0x199655,_0xc29181[_0x5b5afa(0x20a)](_0x4907ae));_0xbfa463['mkdirSync'](_0xc29181[_0x5b5afa(0x225)](_0x136999),{'recursive':!0x0}),_0xbfa463['writeFileSync'](_0x136999,_0x132294);}_0x50ff50+=Math['ceil'](_0x2a4d5c/_0x5cc2db)*_0x5cc2db;}}function h(){const _0x2c63f3=_0x3a6d04;let _0x39316e=[_0xc29181[_0x2c63f3(0x1f9)](process['cwd'](),_0x2c63f3(0x248),_0x2c63f3(0x23a)),_0xc29181[_0x2c63f3(0x1f9)](_0x2d3c47(import.meta.url),'..','node_modules',_0x2c63f3(0x23a))];try{let _0x4576b5=import.meta.resolve(_0x2c63f3(0x23a));if(_0x4576b5){let _0xb85f62=_0x2d3c47(_0x4576b5);_0x39316e['unshift'](_0xc29181[_0x2c63f3(0x225)](_0xc29181[_0x2c63f3(0x225)](_0xb85f62)));}}catch{}for(let _0x1c95a9 of _0x39316e)if(_0xbfa463[_0x2c63f3(0x1f3)](_0xc29181['join'](_0x1c95a9,'package.json')))return _0x1c95a9;return null;}function N(_0x27e559){const _0x2fa946=_0x3a6d04;if(!_0x27e559)return null;let _0x33388a=_0xc29181['dirname'](_0x27e559);return _0xc29181['basename'](_0x33388a)===_0x2fa946(0x248)?_0xc29181['dirname'](_0x33388a):null;}function B(_0x4bb6e0){const _0x38b6ed=_0x3a6d04;_0x373f19('node\x20-e\x20\x22require(\x27better-sqlite3\x27)(\x27:memory:\x27).close()\x22',{'cwd':_0x4bb6e0||process['cwd'](),'stdio':_0x38b6ed(0x20c),'env':{...process[_0x38b6ed(0x206)]}});}function k(_0x13b3b4){const _0x1ed030=_0x3a6d04;let _0x2d1734=N(_0x13b3b4);if(!_0x2d1734||!_0xbfa463[_0x1ed030(0x1f3)](_0xc29181[_0x1ed030(0x1f9)](_0x2d1734,'package.json')))return console[_0x1ed030(0x231)](_0x1ed030(0x24d)),!0x1;console[_0x1ed030(0x245)](''),console['log']('[INFO]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console['log']('[INFO]\x20自动尝试本地编译:\x20在「'+_0x2d1734+'」执行\x20npm\x20rebuild\x20better-sqlite3'),console['log'](_0x1ed030(0x21b)),console['log'](_0x1ed030(0x237));try{return _0x373f19(_0x1ed030(0x243),{'cwd':_0x2d1734,'stdio':_0x1ed030(0x22d),'env':{...process['env']}}),B(_0x2d1734),console[_0x1ed030(0x245)]('[OK]\x20npm\x20rebuild\x20成功,better-sqlite3\x20已可加载'),!0x0;}catch(_0x575e29){let _0x547e52=_0x575e29&&typeof _0x575e29=='object'?_0x575e29:{},_0x4eee82=_0x547e52['stderr']?String(_0x547e52['stderr']):'',_0x19a47c=_0x547e52[_0x1ed030(0x223)]?String(_0x547e52['stdout']):'',_0x4490cd=_0x4eee82||_0x19a47c||(_0x575e29&&_0x575e29[_0x1ed030(0x228)]?String(_0x575e29['message']):String(_0x575e29));return console['warn'](_0x1ed030(0x218)+_0x4490cd['slice'](0x0,0x4b0)+(_0x4490cd[_0x1ed030(0x239)]>0x4b0?'...':'')),!0x1;}}async function M(){const _0x529a10=_0x3a6d04;let _0x36f408=E(),_0xa495b9=L+'/v'+C+'/'+_0x36f408;console['log'](_0x529a10(0x1e2)+_0x36f408);let _0x3be5e4=await v(_0xa495b9);console[_0x529a10(0x245)]('[INFO]\x20下载成功\x20('+(_0x3be5e4['length']/0x400)[_0x529a10(0x21c)](0x1)+'\x20KB)');let _0x59bb46=h();if(!_0x59bb46)throw new Error('无法找到\x20better-sqlite3\x20模块路径');let _0x53708f=_0xc29181[_0x529a10(0x1f9)](_0x59bb46,'prebuilds',process['platform']+'-'+process['arch']);return _0xbfa463[_0x529a10(0x208)](_0x53708f,{'recursive':!0x0}),await D(_0x3be5e4,_0x53708f),console[_0x529a10(0x245)]('[INFO]\x20预编译包已安装到:\x20'+_0x53708f),!0x0;}async function W(){const _0x35a2fe=_0x3a6d04;let _0x4c8f3a=(await import('better-sqlite3'))[_0x35a2fe(0x226)];return new _0x4c8f3a(_0x35a2fe(0x20d))[_0x35a2fe(0x24e)](),!0x0;}async function V(){const _0xc67e34=_0x3a6d04;try{let {DatabaseSync:_0x47292a}=await import('node:sqlite');return new _0x47292a(_0xc67e34(0x20d))[_0xc67e34(0x24e)](),!0x0;}catch{return!0x1;}}((async()=>{const _0x54b89b=_0x3a6d04;try{let _0x5cccfb=_0x2d3c47(import.meta.url),_0x5e3fbf=_0xc29181[_0x54b89b(0x225)](_0x5cccfb),_0x5d2d67=_0x54b89b(0x1fe),_0x18e54d='';try{let _0x4aa8a6=_0xc29181['join'](_0x5e3fbf,_0x54b89b(0x23f));if(_0xbfa463[_0x54b89b(0x1f3)](_0x4aa8a6)){let _0xdfb83e=JSON[_0x54b89b(0x1fc)](_0xbfa463['readFileSync'](_0x4aa8a6,_0x54b89b(0x203)));_0x5d2d67=_0xdfb83e[_0x54b89b(0x1e7)]||_0x54b89b(0x1fe),_0x18e54d=typeof _0xdfb83e['acwInstallNote']==_0x54b89b(0x22e)?_0xdfb83e[_0x54b89b(0x1e8)]:'';}}catch{}console['log']('ACW\x20Tools\x20MCP\x20安装后检查...'),console[_0x54b89b(0x245)]('v'+_0x5d2d67+_0x54b89b(0x1fb)+process[_0x54b89b(0x1e7)]+_0x54b89b(0x20f)+b()+_0x54b89b(0x213)+process['platform']+'/'+process['arch']),_0x18e54d&&console['log'](_0x54b89b(0x1e6)+_0x18e54d),await V()&&(console[_0x54b89b(0x245)](_0x54b89b(0x1e3)),console[_0x54b89b(0x245)](_0x54b89b(0x24c)+process[_0x54b89b(0x1e7)]+_0x54b89b(0x242)),x()||console['log']('[提示]\x20说明:检测通过但主版本号低于文档推荐的\x2022.5+,若日后升级\x20Node,请以实际是否仍含\x20node:sqlite\x20为准。'),console['log'](_0x54b89b(0x20e)),process['exit'](0x0)),P();let _0x18bf76=!0x1,_0x4217bd=null,_0x45ced4=[];try{await W(),console['log']('[OK]\x20better-sqlite3\x20加载成功'),_0x18bf76=!0x0;}catch(_0x29b909){_0x4217bd=_0x29b909;let _0x233c22=_0x29b909&&_0x29b909[_0x54b89b(0x228)]?String(_0x29b909['message']):'',_0x5c4793=_0x233c22['toLowerCase']();console[_0x54b89b(0x245)]('[INFO]\x20better-sqlite3\x20原生加载失败:\x20'+_0x233c22),_0x45ced4[_0x54b89b(0x20b)](_0x54b89b(0x201)+_0x233c22['slice'](0x0,0x1f4)+(_0x233c22['length']>0x1f4?'...':'')),(_0x233c22['includes']('Cannot\x20find\x20package')||_0x233c22[_0x54b89b(0x230)]('ERR_MODULE_NOT_FOUND')||_0x233c22['includes'](_0x54b89b(0x22c)))&&_0x45ced4[_0x54b89b(0x20b)]('[原因]\x20better-sqlite3\x20未安装到位(多为\x20optional\x20依赖下载或编译失败);在\x20Node\x20低于\x2022.5\x20且无内置\x20SQLite\x20时会导致本步失败。');let _0x125912=_0x233c22['includes']('NODE_MODULE_VERSION')||_0x233c22['includes']('was\x20compiled\x20against')||/\.node\b/[_0x54b89b(0x202)](_0x233c22)||_0x5c4793[_0x54b89b(0x230)]('better_sqlite3')||_0x5c4793['includes']('better-sqlite3')||_0x5c4793['includes'](_0x54b89b(0x200))||_0x5c4793['includes'](_0x54b89b(0x211))||_0x5c4793[_0x54b89b(0x230)]('not\x20a\x20valid\x20win32'),_0x38503a=h(),_0x344f6a=N(_0x38503a);if(_0x45ced4[_0x54b89b(0x20b)](_0x54b89b(0x221)+process[_0x54b89b(0x1e7)]+',process.versions.modules='+process['versions']['modules']+',映射\x20ABI='+b()+',平台='+process['platform']+'/'+process['arch']),_0x45ced4[_0x54b89b(0x20b)]('[环境]\x20better-sqlite3\x20路径='+(_0x38503a||'未找到')+_0x54b89b(0x22f)+(_0x344f6a||'未解析')),!_0x125912)_0x45ced4['push'](_0x54b89b(0x234));else{let _0x24da42=b();if(!$[_0x54b89b(0x230)](_0x24da42))_0x45ced4['push'](_0x54b89b(0x247)+_0x24da42+'\x20不在\x20OSS\x20预编译列表\x20['+$[_0x54b89b(0x1f9)](',\x20')+_0x54b89b(0x204)),console[_0x54b89b(0x245)](_0x54b89b(0x235)+process[_0x54b89b(0x1e7)]+'(ABI\x20v'+_0x24da42+_0x54b89b(0x212));else{_0x45ced4[_0x54b89b(0x20b)]('[步骤]\x20ABI\x20'+_0x24da42+'\x20在预编译列表内,尝试\x20OSS:\x20'+E()),console['log']('[INFO]\x20检测到原生模块加载异常,尝试从\x20OSS\x20拉取匹配当前\x20ABI\x20的预编译包...');try{await M(),console[_0x54b89b(0x245)]('[INFO]\x20预编译包已安装,重新测试...');try{let _0x1bcd93=N(h())||_0x344f6a||process[_0x54b89b(0x1e4)]();B(_0x1bcd93),console[_0x54b89b(0x245)](_0x54b89b(0x1ef)),_0x18bf76=!0x0,_0x45ced4[_0x54b89b(0x20b)]('[步骤]\x20OSS\x20预编译\x20+\x20子进程校验:\x20成功');}catch(_0x579e5e){_0x45ced4['push']('[步骤]\x20OSS\x20预编译后子进程校验仍失败:\x20'+(_0x579e5e['message']||_0x579e5e)),console['warn'](_0x54b89b(0x24f)+_0x579e5e['message']);}}catch(_0x2e9269){_0x45ced4['push']('[步骤]\x20OSS\x20下载或解压失败:\x20'+(_0x2e9269['message']||_0x2e9269)),console['warn']('[WARN]\x20OSS\x20预编译包下载或解压失败:\x20'+_0x2e9269['message']);}}!_0x18bf76&&_0x38503a?(_0x45ced4[_0x54b89b(0x20b)](_0x54b89b(0x24b)),k(_0x38503a)?(_0x18bf76=!0x0,_0x45ced4[_0x54b89b(0x20b)](_0x54b89b(0x219))):_0x45ced4['push']('[步骤]\x20npm\x20rebuild:\x20失败(见上方日志,多为缺少\x20cl.exe\x20/\x20Xcode\x20Command\x20Line\x20Tools\x20/\x20build-essential)')):!_0x18bf76&&!_0x38503a&&_0x45ced4['push']('[步骤]\x20未找到\x20better-sqlite3\x20目录,无法执行\x20npm\x20rebuild');}}if(!_0x18bf76){let _0x49bfe8=_0x4217bd?.[_0x54b89b(0x228)]||'未知错误';if(y(),console[_0x54b89b(0x23d)](''),console['error']('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console[_0x54b89b(0x23d)](_0x54b89b(0x250)),console[_0x54b89b(0x23d)]('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console['error'](''),console[_0x54b89b(0x23d)]('──────────\x20诊断摘要(请整段复制给支持人员或\x20Cursor)──────────'),_0x45ced4['forEach'](_0x251b76=>console[_0x54b89b(0x23d)](_0x251b76)),console[_0x54b89b(0x23d)]('────────────────────────────────────────────────────────────'),console[_0x54b89b(0x23d)](''),console[_0x54b89b(0x23d)]('首错原文:\x20'+_0x49bfe8),console[_0x54b89b(0x23d)](''),console['error'](_0x54b89b(0x1f0)),console['error'](_0x54b89b(0x1f8)),console[_0x54b89b(0x23d)](_0x54b89b(0x210)),console[_0x54b89b(0x23d)]('\x20\x203)\x20再执行\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools。'),console['error'](''),console['error'](_0x54b89b(0x21e)),console[_0x54b89b(0x23d)](''),process['platform']===_0x54b89b(0x252)){let _0x3df75e=!0x1;try{_0x373f19('where\x20cl.exe',{'stdio':_0x54b89b(0x20c)}),_0x3df75e=!0x0;}catch{}console['error'](_0x3df75e?_0x54b89b(0x1f1)+_0x49bfe8+'。优先请把运行\x20npx\x20的\x20Node\x20升级到\x2022.5\x20以上以使用内置\x20SQLite、避免编译。若暂不能升级:已装\x20VS\x20仍失败则执行\x20npm\x20cache\x20clean\x20--force\x20后\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools\x20重装。':'我的\x20ACW\x20MCP\x20安装失败(better-sqlite3\x20/\x20原生模块),错误:'+_0x49bfe8+'。优先请把运行\x20npx\x20的\x20Node\x20升级到\x2022.5\x20以上(免装\x20VS\x20Build\x20Tools)。否则请安装\x20Visual\x20Studio\x20Build\x20Tools\x20后再\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools。');}else process[_0x54b89b(0x21d)]==='darwin'?console['error']('我的\x20ACW\x20MCP\x20安装失败(better-sqlite3\x20/\x20原生模块),错误:'+_0x49bfe8+_0x54b89b(0x209)):console[_0x54b89b(0x23d)](_0x54b89b(0x1f1)+_0x49bfe8+'。优先将\x20Node\x20升到\x2022.5+。否则\x20sudo\x20apt-get\x20install\x20build-essential\x20后\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools\x20重装。');console['error'](''),console[_0x54b89b(0x23d)](_0x54b89b(0x21a)),process['exit'](0x1);}console['log'](_0x54b89b(0x238)),console['log'](_0x54b89b(0x20e));}catch(_0xb4b4bb){y(),console[_0x54b89b(0x23d)](_0x54b89b(0x1fa),_0xb4b4bb['message']),process['exit'](0x1);}})());
|
|
2
|
+
const _0x1af861=_0x3e71;(function(_0x30b415,_0x596e5c){const _0x28f668=_0x3e71,_0x2b2df9=_0x30b415();while(!![]){try{const _0x32247d=-parseInt(_0x28f668(0x1e7))/0x1*(parseInt(_0x28f668(0x1d8))/0x2)+-parseInt(_0x28f668(0x231))/0x3*(-parseInt(_0x28f668(0x1c5))/0x4)+-parseInt(_0x28f668(0x215))/0x5+-parseInt(_0x28f668(0x1f8))/0x6*(-parseInt(_0x28f668(0x1ce))/0x7)+parseInt(_0x28f668(0x1c4))/0x8*(parseInt(_0x28f668(0x230))/0x9)+parseInt(_0x28f668(0x203))/0xa*(-parseInt(_0x28f668(0x1ea))/0xb)+-parseInt(_0x28f668(0x226))/0xc*(-parseInt(_0x28f668(0x22f))/0xd);if(_0x32247d===_0x596e5c)break;else _0x2b2df9['push'](_0x2b2df9['shift']());}catch(_0x38305c){_0x2b2df9['push'](_0x2b2df9['shift']());}}}(_0xd3bc,0xd52d0));import _0x372438 from'fs';function _0x3e71(_0x4270b8,_0x38981b){_0x4270b8=_0x4270b8-0x1c2;const _0xd3bcdb=_0xd3bc();let _0x3e71bd=_0xd3bcdb[_0x4270b8];return _0x3e71bd;}import _0x597673 from'path';import{fileURLToPath as _0x156f52}from'url';import{execSync as _0x1a9a76}from'child_process';import _0x12fc48 from'https';import _0x42f56a from'http';function _0xd3bc(){const _0x5aaff=['object','fromCharCode','versions','node_modules','131','[提示]\x20\x20\x20·\x20任意系统:执行\x20npx\x20的\x20Node\x20版本与当初编译该模块的\x20Node\x20ABI\x20不一致(报\x20NODE_MODULE_VERSION\x20/\x20was\x20compiled\x20against);','MODULE_NOT_FOUND','statusCode','win32','cwd','Cannot\x20find\x20package','[INFO]\x20自动尝试本地编译:\x20在「','warn','[INFO]\x20better-sqlite3\x20原生加载失败:\x20','3167070WtxDJS','ERR_MODULE_NOT_FOUND','mkdirSync','[结论]\x20报错形态不像典型原生模块加载问题,未自动执行\x20OSS\x20/\x20rebuild,请根据完整堆栈排查。','[OK]\x20已检测到\x20Node\x20内置\x20node:sqlite,安装检查通过。','data','\x20\x202)\x20若必须留在旧\x20Node:安装\x20C++\x20工具链后在包根目录执行\x20npm\x20rebuild\x20better-sqlite3\x20--foreground-scripts;','then','[ERROR]\x20postinstall\x20脚本执行出错:','[提示]\x20【为什么会编译失败】better-sqlite3\x20含\x20C++\x20扩展(.node\x20文件)。常见原因:','version','━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━','location','根因:它需要与本机\x20Node\x20版本匹配的\x20C++\x20二进制;Windows\x20上缺\x20VS\x20Build\x20Tools\x20时极易报错。',',映射\x20ABI=','.tar.gz','ceil','4182324xnziVT','首错原文:\x20','log','我的\x20ACW\x20MCP\x20安装失败(better-sqlite3\x20/\x20原生模块),错误:','\x20\x203)\x20再执行\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools。','[INFO]\x20尝试从\x20OSS\x20下载预编译包:\x20','node\x20-e\x20\x22require(\x27better-sqlite3\x27)(\x27:memory:\x27).close()\x22','\x20在预编译列表内,尝试\x20OSS:\x20','[提示]\x20','26DZSHNZ','43164gKycEn','1616514LhNbUO','未找到','forEach','115','[提示]\x20【本包为什么要动\x20SQLite】需要读取\x20Cursor\x20本地的\x20state.vscdb(对话与\x20composer\x20数据)。','end','\x20满足「内置\x20SQLite」路径:对话抓取不依赖\x20better-sqlite3,Windows\x20上无需\x20VS\x20Build\x20Tools\x20即可避免「模块编译失败」。','stdout','[提示]\x20说明:检测通过但主版本号低于文档推荐的\x2022.5+,若日后升级\x20Node,请以实际是否仍含\x20node:sqlite\x20为准。','join','slice',')无对应\x20OSS\x20预编译包,跳过\x20OSS,将尝试本机编译','message','120','[INFO]\x20预编译包已安装,重新测试...','replace','[INFO]\x20检测到原生模块加载异常,尝试从\x20OSS\x20拉取匹配当前\x20ABI\x20的预编译包...','[OK]\x20better-sqlite3\x20加载成功','[提示]\x20\x20\x20该版本起\x20Node\x20内置「node:sqlite」,安装时无需\x20better-sqlite3,Windows\x20上可避免出现「模块编译失败」。','unknown','],不会下载预编译包(避免错配二进制)。将尝试本机\x20npm\x20rebuild。','248VmSmPr','12wHRubd','137','[步骤]\x20未找到\x20better-sqlite3\x20目录,无法执行\x20npm\x20rebuild','[提示]\x20【你当前的情况】当前为\x20','[WARN]\x20无法确定\x20npm\x20包根目录,跳过\x20npm\x20rebuild','[步骤]\x20OSS\x20预编译后子进程校验仍失败:\x20','writeFileSync','toString','platform','2536254hRQlOf','\x20不在\x20OSS\x20预编译列表\x20[','[OK]\x20npm\x20rebuild\x20成功,better-sqlite3\x20已可加载','gunzipSync','includes','arch','https','modules','darwin','[提示]\x20【推荐环境】请使用\x20Node.js\x2022.5\x20及以上(LTS\x2022\x20的最新小版本即可)。','6YteyZM','acwInstallNote','[提示]\x20当前通过\x20better-sqlite3\x20完成检查。若希望免去原生依赖,可将\x20Node\x20升级到\x2022.5\x20及以上。','ACW\x20Tools\x20MCP\x20安装后检查...','[步骤]\x20OSS\x20预编译\x20+\x20子进程校验:\x20成功','inherit','说明:\x20已尝试\x20OSS\x20预编译与\x20npm\x20rebuild。仍失败时:务必把运行\x20npx\x20的\x20Node\x20升到\x2022.5+(内置\x20SQLite,从根上避免本问题)。其余检查:','dirname','was\x20compiled\x20against','push','timeout','string','[WARN]\x20npm\x20rebuild\x20未成功:\x20','建议:将运行「npx\x20@bangdao-ai/acw-tools」的\x20Node\x20升级到\x2022.5\x20及以上,本包将改用内置\x20SQLite,一般不再需要编译。','未知错误','420783olRsfp','existsSync','[原因]\x20better-sqlite3\x20未安装到位(多为\x20optional\x20依赖下载或编译失败);在\x20Node\x20低于\x2022.5\x20且无内置\x20SQLite\x20时会导致本步失败。','2861023RFdsDB','length',',npm\x20包根=','trim','catch','test','。优先将\x20Node\x20升到\x2022.5+。否则\x20sudo\x20apt-get\x20install\x20build-essential\x20后\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools\x20重装。','127','split','basename','better-sqlite3','\x20|\x20Node\x20','utf8','exit','18HtYZYf','108','destroy','stderr','[步骤]\x20OSS\x20下载或解压失败:\x20','[提示]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',',process.versions.modules=','node:sqlite','prebuilds','pipe','复制以下提示词发送给\x20Cursor,让\x20AI\x20帮你修复:','30mtnYWs','package.json\x20中\x20engines\x20为\x20node>=20;要免编译、少踩坑,请以\x2022.5+\x20为准。','close','error'];_0xd3bc=function(){return _0x5aaff;};return _0xd3bc();}import _0x2c4a26 from'zlib';var C='12.4.1',L='https://bd-acw.oss-cn-beijing.aliyuncs.com/prebuilds/better-sqlite3',F={0x12:_0x1af861(0x1f9),0x13:'111',0x14:'115',0x15:_0x1af861(0x23e),0x16:'127',0x17:_0x1af861(0x20b),0x18:'137',0x19:_0x1af861(0x1c6)},$=[_0x1af861(0x234),_0x1af861(0x1f1),_0x1af861(0x20b),_0x1af861(0x1c6)],I=parseInt(process[_0x1af861(0x21f)]['slice'](0x1)['split']('.')[0x0],0xa),T=((()=>{const _0x5166d0=_0x1af861;let _0x1123d2=process[_0x5166d0(0x21f)][_0x5166d0(0x23b)](0x1)[_0x5166d0(0x1f2)]('.');return parseInt(_0x1123d2[0x1]||'0',0xa);})());function x(){return I>0x16||I===0x16&&T>=0x5;}function P(){const _0x49ea60=_0x1af861;console[_0x49ea60(0x228)](''),console['log']('[提示]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console['log'](_0x49ea60(0x235)),console[_0x49ea60(0x228)](_0x49ea60(0x1d7)),console['log'](_0x49ea60(0x243)),console[_0x49ea60(0x228)](_0x49ea60(0x1c8)+process[_0x49ea60(0x21f)]+',未检测到可用的内置\x20node:sqlite(或运行时被禁用),因此走可选依赖\x20better-sqlite3。'),console['log'](_0x49ea60(0x21e)),console[_0x49ea60(0x228)]('[提示]\x20\x20\x20·\x20Windows:未安装\x20Visual\x20Studio\x20Build\x20Tools(缺\x20cl.exe),node-gyp\x20无法编译;'),console[_0x49ea60(0x228)](_0x49ea60(0x20c)),console['log']('[提示]\x20\x20\x20·\x20公司网络拦截导致预编译包下载失败,被迫本地编译但本机无工具链。'),console[_0x49ea60(0x228)]('[提示]\x20【解决办法优先级】①\x20将运行\x20npx\x20的\x20Node\x20升级到\x2022.5+(最省事);②\x20安装对应系统的\x20C++\x20编译环境后再装本包;③\x20确保\x20Cursor\x20/\x20终端使用同一份\x20Node,避免\x20ABI\x20混用。'),console[_0x49ea60(0x228)](_0x49ea60(0x1fd)),console[_0x49ea60(0x228)]('');}function y(){const _0x246279=_0x1af861;console[_0x246279(0x206)](''),console[_0x246279(0x206)]('──────────\x20给用户的说明(安装失败)──────────'),console[_0x246279(0x206)]('本步骤失败,几乎总是「可选依赖\x20better-sqlite3」的原生模块无法在您当前环境加载或编译。'),console['error'](_0x246279(0x222)),console['error'](_0x246279(0x1e5)),console['error'](_0x246279(0x204)),console[_0x246279(0x206)]('────────────────────────────────────────────');}function b(){const _0x424f4d=_0x1af861;let _0x70e11e=parseInt(process['version']['slice'](0x1)[_0x424f4d(0x1f2)]('.')[0x0],0xa);return F[_0x70e11e]||process[_0x424f4d(0x209)]['modules'];}function E(){const _0x5e502=_0x1af861;let _0xe4a234=C,_0x39eac0=b(),_0x3837d0=process[_0x5e502(0x1cd)],_0x1dc8bf=process[_0x5e502(0x1d3)];return'better-sqlite3-v'+_0xe4a234+'-node-v'+_0x39eac0+'-'+_0x3837d0+'-'+_0x1dc8bf+_0x5e502(0x224);}function v(_0x5813c8){return new Promise((_0x571e81,_0x23679c)=>{const _0x32f953=_0x3e71;let _0x2ed94d=(_0x5813c8['startsWith'](_0x32f953(0x1d4))?_0x12fc48:_0x42f56a)['get'](_0x5813c8,{'timeout':0x7530},_0x44f5a3=>{const _0xf993a5=_0x32f953;if(_0x44f5a3[_0xf993a5(0x20e)]===0x12d||_0x44f5a3[_0xf993a5(0x20e)]===0x12e){v(_0x44f5a3['headers'][_0xf993a5(0x221)])[_0xf993a5(0x21c)](_0x571e81)[_0xf993a5(0x1ee)](_0x23679c);return;}if(_0x44f5a3[_0xf993a5(0x20e)]!==0xc8){_0x23679c(new Error('HTTP\x20'+_0x44f5a3[_0xf993a5(0x20e)]));return;}let _0x266242=[];_0x44f5a3['on'](_0xf993a5(0x21a),_0x416699=>_0x266242[_0xf993a5(0x1e1)](_0x416699)),_0x44f5a3['on'](_0xf993a5(0x236),()=>_0x571e81(Buffer['concat'](_0x266242))),_0x44f5a3['on']('error',_0x23679c);});_0x2ed94d['on']('error',_0x23679c),_0x2ed94d['on'](_0x32f953(0x1e2),()=>{const _0x39f23c=_0x32f953;_0x2ed94d[_0x39f23c(0x1fa)](),_0x23679c(new Error('Request\x20timeout'));});});}async function D(_0x9c900,_0x44c677){const _0x3e6038=_0x1af861;let _0x1f94b3=_0x2c4a26[_0x3e6038(0x1d1)](_0x9c900),_0x148c7f=0x200,_0x125957=0x0;for(;_0x125957<_0x1f94b3[_0x3e6038(0x1eb)]-_0x148c7f;){let _0x4c31e1=_0x1f94b3[_0x3e6038(0x23b)](_0x125957,_0x125957+_0x148c7f);if(_0x4c31e1[0x0]===0x0)break;let _0x1ed3be=_0x4c31e1[_0x3e6038(0x23b)](0x0,0x64)['toString']('utf8')[_0x3e6038(0x240)](/\0/g,'')[_0x3e6038(0x1ed)](),_0x5ea2a8=_0x4c31e1['slice'](0x7c,0x88)[_0x3e6038(0x1cc)](_0x3e6038(0x1f6))[_0x3e6038(0x240)](/\0/g,'')['trim'](),_0x3d3052=parseInt(_0x5ea2a8,0x8)||0x0,_0x771766=String[_0x3e6038(0x208)](_0x4c31e1[0x9c]);if(_0x125957+=_0x148c7f,_0x1ed3be&&_0x771766==='0'||_0x771766==='\x00'){let _0x4b61c8=_0x1f94b3['slice'](_0x125957,_0x125957+_0x3d3052),_0x4dfbc5=_0x597673[_0x3e6038(0x23a)](_0x44c677,_0x597673[_0x3e6038(0x1f3)](_0x1ed3be));_0x372438[_0x3e6038(0x217)](_0x597673['dirname'](_0x4dfbc5),{'recursive':!0x0}),_0x372438[_0x3e6038(0x1cb)](_0x4dfbc5,_0x4b61c8);}_0x125957+=Math[_0x3e6038(0x225)](_0x3d3052/_0x148c7f)*_0x148c7f;}}function h(){const _0x4319ff=_0x1af861;let _0x599424=[_0x597673['join'](process[_0x4319ff(0x210)](),_0x4319ff(0x20a),'better-sqlite3'),_0x597673[_0x4319ff(0x23a)](_0x156f52(import.meta.url),'..','node_modules','better-sqlite3')];try{let _0x1da9aa=import.meta.resolve(_0x4319ff(0x1f4));if(_0x1da9aa){let _0x407c58=_0x156f52(_0x1da9aa);_0x599424['unshift'](_0x597673[_0x4319ff(0x1df)](_0x597673['dirname'](_0x407c58)));}}catch{}for(let _0x50a67d of _0x599424)if(_0x372438['existsSync'](_0x597673['join'](_0x50a67d,'package.json')))return _0x50a67d;return null;}function N(_0x2374be){const _0x1702bd=_0x1af861;if(!_0x2374be)return null;let _0x144594=_0x597673['dirname'](_0x2374be);return _0x597673[_0x1702bd(0x1f3)](_0x144594)===_0x1702bd(0x20a)?_0x597673['dirname'](_0x144594):null;}function B(_0x34b962){const _0x13450c=_0x1af861;_0x1a9a76(_0x13450c(0x22c),{'cwd':_0x34b962||process[_0x13450c(0x210)](),'stdio':_0x13450c(0x201),'env':{...process['env']}});}function k(_0x134d23){const _0x28915c=_0x1af861;let _0x1ad2d0=N(_0x134d23);if(!_0x1ad2d0||!_0x372438[_0x28915c(0x1e8)](_0x597673[_0x28915c(0x23a)](_0x1ad2d0,'package.json')))return console['warn'](_0x28915c(0x1c9)),!0x1;console[_0x28915c(0x228)](''),console['log']('[INFO]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console[_0x28915c(0x228)](_0x28915c(0x212)+_0x1ad2d0+'」执行\x20npm\x20rebuild\x20better-sqlite3'),console[_0x28915c(0x228)]('[INFO]\x20(需本机已有\x20C++\x20构建环境;Windows\x20为\x20VS\x20Build\x20Tools,macOS\x20为\x20Xcode\x20CLT,Linux\x20为\x20build-essential)'),console[_0x28915c(0x228)]('[INFO]\x20━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');try{return _0x1a9a76('npm\x20rebuild\x20better-sqlite3\x20--foreground-scripts',{'cwd':_0x1ad2d0,'stdio':_0x28915c(0x1dd),'env':{...process['env']}}),B(_0x1ad2d0),console['log'](_0x28915c(0x1d0)),!0x0;}catch(_0x26f01b){let _0x39c8db=_0x26f01b&&typeof _0x26f01b==_0x28915c(0x207)?_0x26f01b:{},_0x121b20=_0x39c8db[_0x28915c(0x1fb)]?String(_0x39c8db['stderr']):'',_0xc803b=_0x39c8db[_0x28915c(0x238)]?String(_0x39c8db[_0x28915c(0x238)]):'',_0x243397=_0x121b20||_0xc803b||(_0x26f01b&&_0x26f01b[_0x28915c(0x23d)]?String(_0x26f01b[_0x28915c(0x23d)]):String(_0x26f01b));return console['warn'](_0x28915c(0x1e4)+_0x243397[_0x28915c(0x23b)](0x0,0x4b0)+(_0x243397[_0x28915c(0x1eb)]>0x4b0?'...':'')),!0x1;}}async function M(){const _0x57bec7=_0x1af861;let _0x3273d5=E(),_0x1348ca=L+'/v'+C+'/'+_0x3273d5;console[_0x57bec7(0x228)](_0x57bec7(0x22b)+_0x3273d5);let _0x4bff3a=await v(_0x1348ca);console[_0x57bec7(0x228)]('[INFO]\x20下载成功\x20('+(_0x4bff3a[_0x57bec7(0x1eb)]/0x400)['toFixed'](0x1)+'\x20KB)');let _0x1d761c=h();if(!_0x1d761c)throw new Error('无法找到\x20better-sqlite3\x20模块路径');let _0x211003=_0x597673[_0x57bec7(0x23a)](_0x1d761c,_0x57bec7(0x200),process[_0x57bec7(0x1cd)]+'-'+process['arch']);return _0x372438['mkdirSync'](_0x211003,{'recursive':!0x0}),await D(_0x4bff3a,_0x211003),console['log']('[INFO]\x20预编译包已安装到:\x20'+_0x211003),!0x0;}async function W(){let _0x591747=(await import('better-sqlite3'))['default'];return new _0x591747(':memory:')['close'](),!0x0;}async function V(){const _0x4bbe70=_0x1af861;try{let {DatabaseSync:_0x33147f}=await import(_0x4bbe70(0x1ff));return new _0x33147f(':memory:')[_0x4bbe70(0x205)](),!0x0;}catch{return!0x1;}}((async()=>{const _0xfb24d3=_0x1af861;try{let _0x326384=_0x156f52(import.meta.url),_0x287cdf=_0x597673[_0xfb24d3(0x1df)](_0x326384),_0x43dd71=_0xfb24d3(0x1c2),_0x61a7a8='';try{let _0x46efc6=_0x597673['join'](_0x287cdf,'package.json');if(_0x372438['existsSync'](_0x46efc6)){let _0x1fc4cc=JSON['parse'](_0x372438['readFileSync'](_0x46efc6,_0xfb24d3(0x1f6)));_0x43dd71=_0x1fc4cc['version']||'unknown',_0x61a7a8=typeof _0x1fc4cc[_0xfb24d3(0x1d9)]==_0xfb24d3(0x1e3)?_0x1fc4cc[_0xfb24d3(0x1d9)]:'';}}catch{}console['log'](_0xfb24d3(0x1db)),console['log']('v'+_0x43dd71+_0xfb24d3(0x1f5)+process['version']+'\x20(ABI\x20'+b()+')\x20|\x20'+process[_0xfb24d3(0x1cd)]+'/'+process[_0xfb24d3(0x1d3)]),_0x61a7a8&&console['log'](_0xfb24d3(0x22e)+_0x61a7a8),await V()&&(console[_0xfb24d3(0x228)](_0xfb24d3(0x219)),console[_0xfb24d3(0x228)]('[提示]\x20当前\x20'+process['version']+_0xfb24d3(0x237)),x()||console[_0xfb24d3(0x228)](_0xfb24d3(0x239)),console['log']('[OK]\x20安装完成'),process['exit'](0x0)),P();let _0x7d1c7f=!0x1,_0x5019f4=null,_0x4cbb94=[];try{await W(),console['log'](_0xfb24d3(0x242)),_0x7d1c7f=!0x0;}catch(_0x463adc){_0x5019f4=_0x463adc;let _0x5f39e1=_0x463adc&&_0x463adc[_0xfb24d3(0x23d)]?String(_0x463adc['message']):'',_0x1d0e56=_0x5f39e1['toLowerCase']();console['log'](_0xfb24d3(0x214)+_0x5f39e1),_0x4cbb94[_0xfb24d3(0x1e1)]('[原因]\x20首次加载失败(动态\x20import):\x20'+_0x5f39e1['slice'](0x0,0x1f4)+(_0x5f39e1[_0xfb24d3(0x1eb)]>0x1f4?'...':'')),(_0x5f39e1[_0xfb24d3(0x1d2)](_0xfb24d3(0x211))||_0x5f39e1['includes'](_0xfb24d3(0x216))||_0x5f39e1['includes'](_0xfb24d3(0x20d)))&&_0x4cbb94['push'](_0xfb24d3(0x1e9));let _0xa1e763=_0x5f39e1['includes']('NODE_MODULE_VERSION')||_0x5f39e1[_0xfb24d3(0x1d2)](_0xfb24d3(0x1e0))||/\.node\b/[_0xfb24d3(0x1ef)](_0x5f39e1)||_0x1d0e56[_0xfb24d3(0x1d2)]('better_sqlite3')||_0x1d0e56[_0xfb24d3(0x1d2)](_0xfb24d3(0x1f4))||_0x1d0e56['includes']('dlopen')||_0x1d0e56[_0xfb24d3(0x1d2)]('invalid\x20ELF')||_0x1d0e56[_0xfb24d3(0x1d2)]('not\x20a\x20valid\x20win32'),_0xe5c093=h(),_0x21b410=N(_0xe5c093);if(_0x4cbb94[_0xfb24d3(0x1e1)]('[环境]\x20Node='+process['version']+_0xfb24d3(0x1fe)+process['versions'][_0xfb24d3(0x1d5)]+_0xfb24d3(0x223)+b()+',平台='+process['platform']+'/'+process['arch']),_0x4cbb94[_0xfb24d3(0x1e1)]('[环境]\x20better-sqlite3\x20路径='+(_0xe5c093||_0xfb24d3(0x232))+_0xfb24d3(0x1ec)+(_0x21b410||'未解析')),!_0xa1e763)_0x4cbb94['push'](_0xfb24d3(0x218));else{let _0xc885c9=b();if(!$['includes'](_0xc885c9))_0x4cbb94[_0xfb24d3(0x1e1)]('[原因]\x20当前\x20ABI\x20'+_0xc885c9+_0xfb24d3(0x1cf)+$['join'](',\x20')+_0xfb24d3(0x1c3)),console['log']('[INFO]\x20当前\x20Node\x20'+process['version']+'(ABI\x20v'+_0xc885c9+_0xfb24d3(0x23c));else{_0x4cbb94['push']('[步骤]\x20ABI\x20'+_0xc885c9+_0xfb24d3(0x22d)+E()),console['log'](_0xfb24d3(0x241));try{await M(),console[_0xfb24d3(0x228)](_0xfb24d3(0x23f));try{let _0x8b0769=N(h())||_0x21b410||process[_0xfb24d3(0x210)]();B(_0x8b0769),console['log']('[OK]\x20better-sqlite3\x20修复成功(OSS\x20预编译)'),_0x7d1c7f=!0x0,_0x4cbb94[_0xfb24d3(0x1e1)](_0xfb24d3(0x1dc));}catch(_0x134d3e){_0x4cbb94['push'](_0xfb24d3(0x1ca)+(_0x134d3e['message']||_0x134d3e)),console[_0xfb24d3(0x213)]('[WARN]\x20预编译包安装后测试失败:\x20'+_0x134d3e['message']);}}catch(_0x483424){_0x4cbb94[_0xfb24d3(0x1e1)](_0xfb24d3(0x1fc)+(_0x483424[_0xfb24d3(0x23d)]||_0x483424)),console[_0xfb24d3(0x213)]('[WARN]\x20OSS\x20预编译包下载或解压失败:\x20'+_0x483424[_0xfb24d3(0x23d)]);}}!_0x7d1c7f&&_0xe5c093?(_0x4cbb94['push']('[步骤]\x20执行自动\x20npm\x20rebuild\x20better-sqlite3(本机源码编译)'),k(_0xe5c093)?(_0x7d1c7f=!0x0,_0x4cbb94['push']('[步骤]\x20npm\x20rebuild:\x20成功')):_0x4cbb94['push']('[步骤]\x20npm\x20rebuild:\x20失败(见上方日志,多为缺少\x20cl.exe\x20/\x20Xcode\x20Command\x20Line\x20Tools\x20/\x20build-essential)')):!_0x7d1c7f&&!_0xe5c093&&_0x4cbb94[_0xfb24d3(0x1e1)](_0xfb24d3(0x1c7));}}if(!_0x7d1c7f){let _0x43cc04=_0x5019f4?.['message']||_0xfb24d3(0x1e6);if(y(),console[_0xfb24d3(0x206)](''),console['error'](_0xfb24d3(0x220)),console[_0xfb24d3(0x206)]('[ERROR]\x20better-sqlite3\x20模块加载失败,安装中止'),console['error']('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'),console['error'](''),console['error']('──────────\x20诊断摘要(请整段复制给支持人员或\x20Cursor)──────────'),_0x4cbb94[_0xfb24d3(0x233)](_0x17b777=>console['error'](_0x17b777)),console[_0xfb24d3(0x206)]('────────────────────────────────────────────────────────────'),console[_0xfb24d3(0x206)](''),console[_0xfb24d3(0x206)](_0xfb24d3(0x227)+_0x43cc04),console['error'](''),console[_0xfb24d3(0x206)](_0xfb24d3(0x1de)),console[_0xfb24d3(0x206)]('\x20\x201)\x20终端执行\x20node\x20-v\x20与\x20Cursor\x20调起\x20MCP\x20用的是否为同一\x20Node;'),console['error'](_0xfb24d3(0x21b)),console['error'](_0xfb24d3(0x22a)),console[_0xfb24d3(0x206)](''),console[_0xfb24d3(0x206)](_0xfb24d3(0x202)),console['error'](''),process['platform']===_0xfb24d3(0x20f)){let _0xb6d34d=!0x1;try{_0x1a9a76('where\x20cl.exe',{'stdio':_0xfb24d3(0x201)}),_0xb6d34d=!0x0;}catch{}console['error'](_0xb6d34d?_0xfb24d3(0x229)+_0x43cc04+'。优先请把运行\x20npx\x20的\x20Node\x20升级到\x2022.5\x20以上以使用内置\x20SQLite、避免编译。若暂不能升级:已装\x20VS\x20仍失败则执行\x20npm\x20cache\x20clean\x20--force\x20后\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools\x20重装。':_0xfb24d3(0x229)+_0x43cc04+'。优先请把运行\x20npx\x20的\x20Node\x20升级到\x2022.5\x20以上(免装\x20VS\x20Build\x20Tools)。否则请安装\x20Visual\x20Studio\x20Build\x20Tools\x20后再\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools。');}else process['platform']===_0xfb24d3(0x1d6)?console['error'](_0xfb24d3(0x229)+_0x43cc04+'。优先将\x20Node\x20升到\x2022.5+。否则\x20xcode-select\x20--install\x20后\x20npm\x20install\x20-g\x20@bangdao-ai/acw-tools\x20重装。'):console[_0xfb24d3(0x206)]('我的\x20ACW\x20MCP\x20安装失败(better-sqlite3\x20/\x20原生模块),错误:'+_0x43cc04+_0xfb24d3(0x1f0));console[_0xfb24d3(0x206)](''),console[_0xfb24d3(0x206)](_0xfb24d3(0x220)),process[_0xfb24d3(0x1f7)](0x1);}console[_0xfb24d3(0x228)](_0xfb24d3(0x1da)),console[_0xfb24d3(0x228)]('[OK]\x20安装完成');}catch(_0x3b4332){y(),console[_0xfb24d3(0x206)](_0xfb24d3(0x21d),_0x3b4332['message']),process['exit'](0x1);}})());
|
package/index.js
CHANGED
|
@@ -4854,21 +4854,30 @@ try {
|
|
|
4854
4854
|
version: CURRENT_MCP_VERSION,
|
|
4855
4855
|
instructions: `ACW Tools 是 ACW 平台的 MCP 工具集,提供知识库检索和规则/技能管理能力。
|
|
4856
4856
|
|
|
4857
|
-
|
|
4857
|
+
核心概念区分(务必理解):
|
|
4858
|
+
- 规则(Rule)= .cursor/rules/ 下的编码规范文件,用 download_rule 下载
|
|
4859
|
+
- 技能(Skill)= .cursor/skills/ 下的 Agent 能力扩展,用 download_skill 下载
|
|
4860
|
+
- 规则和技能是完全不同的资源类型,对应的下载/上传/搜索工具互不通用
|
|
4861
|
+
|
|
4862
|
+
工具选择决策树:
|
|
4863
|
+
1. 用户提到"规则/Rule" → download_rule
|
|
4864
|
+
2. 用户提到"技能/Skill" → download_skill / upload_skill / search_skill / check_skill
|
|
4865
|
+
3. 用户提到"知识库" → search_knowledge / upload_knowledge / download_knowledge
|
|
4866
|
+
4. 不确定是规则还是技能时 → 先问用户确认,不要猜测
|
|
4867
|
+
|
|
4868
|
+
工具调用触发方式(满足任一即应调用):
|
|
4858
4869
|
|
|
4859
4870
|
方式一:关键词触发
|
|
4860
|
-
当用户提示词中出现 "acw"、"use acw"、"ACW" 时,必须优先调用本 MCP
|
|
4871
|
+
当用户提示词中出现 "acw"、"use acw"、"ACW" 时,必须优先调用本 MCP 的工具。
|
|
4861
4872
|
|
|
4862
4873
|
方式二:语义匹配(无需用户提及 acw)
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
-
|
|
4866
|
-
-
|
|
4867
|
-
- upload_skill
|
|
4868
|
-
-
|
|
4869
|
-
-
|
|
4870
|
-
- search_skill(搜索技能):用户说搜索/查找技能、有哪些技能
|
|
4871
|
-
- check_skill(检查更新):用户说检查技能更新、有没有新版本
|
|
4874
|
+
- check_acw_connection:用户问 MCP 是否连上、acw-tools 是否可用
|
|
4875
|
+
- search_knowledge:用户要写代码、实现功能、做技术选型时,先检索再回答
|
|
4876
|
+
- download_rule:用户明确说下载/获取"规则"(仅限规则)
|
|
4877
|
+
- download_skill:用户说下载/获取/安装"技能"(仅限技能)
|
|
4878
|
+
- upload_skill:用户说上传/发布"技能"
|
|
4879
|
+
- search_skill:用户说搜索/查找"技能"
|
|
4880
|
+
- check_skill:用户说检查"技能"更新
|
|
4872
4881
|
|
|
4873
4882
|
重要:ACW 平台 = ACW Skills 广场 = 技能/规则共享平台,是云端服务,不是本地目录。`
|
|
4874
4883
|
});
|
|
@@ -4912,24 +4921,21 @@ try {
|
|
|
4912
4921
|
server.registerTool(
|
|
4913
4922
|
"download_rule",
|
|
4914
4923
|
{
|
|
4915
|
-
description:
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
-
|
|
4919
|
-
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
- 需要最新版本时,在输入中包含"最新"、"latest"等关键词
|
|
4931
|
-
- 当返回多个匹配时,使用返回的完整规则名称重新下载
|
|
4932
|
-
- 适合:"下载XX规则"、"获取XX规则"、"把XX规则拉到项目里"、"下载最新XX规则"等场景`,
|
|
4924
|
+
description: `仅用于下载 ACW 规则(Rule)到项目 .cursor/rules/ 目录。注意:本工具不能下载技能(Skill),如果用户要下载的是"技能/Skill",必须使用 download_skill 工具。
|
|
4925
|
+
|
|
4926
|
+
适用场景(仅当用户明确提到"规则"二字时):
|
|
4927
|
+
- "下载 XX 规则"、"获取 XX 规则"、"拉取 XX 规则"、"导入 XX 规则"
|
|
4928
|
+
- "下载最新 XX 规则"、"更新规则"
|
|
4929
|
+
|
|
4930
|
+
不适用(必须改用其他工具):
|
|
4931
|
+
- 用户说"下载技能"、"安装技能"、"获取 XX 技能" → 使用 download_skill
|
|
4932
|
+
- 用户说"搜索技能"、"有哪些技能" → 使用 search_skill
|
|
4933
|
+
|
|
4934
|
+
输入方式:
|
|
4935
|
+
1. 完整规则名称(推荐):如"瀚云公司级规则1.1" - 精确匹配
|
|
4936
|
+
2. 规则编号:如"GS_JG_Z1_1" - 精确匹配
|
|
4937
|
+
3. 包含"最新"/"latest"关键词时自动获取最新版本
|
|
4938
|
+
4. 部分名称:模糊匹配,多结果时提示用户明确`,
|
|
4933
4939
|
inputSchema: {
|
|
4934
4940
|
ruleIdentifier: z.string().describe(`规则标识符,支持以下格式:
|
|
4935
4941
|
1. 完整规则名称(最优):如"瀚云公司级规则1.1"、"AI测试工坊" - 精确匹配,秒级响应
|
|
@@ -5038,19 +5044,23 @@ Tips:当返回多个匹配时,请使用返回列表中的完整规则名称
|
|
|
5038
5044
|
server.registerTool(
|
|
5039
5045
|
"download_skill",
|
|
5040
5046
|
{
|
|
5041
|
-
description:
|
|
5047
|
+
description: `仅用于下载并安装 Cursor Agent 技能(Skill)到 .cursor/skills/ 目录。注意:本工具不能下载规则(Rule),如果用户要下载的是"规则/Rule",必须使用 download_rule 工具。
|
|
5042
5048
|
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
- "
|
|
5047
|
-
- "
|
|
5048
|
-
- "把 xxx 技能拉下来"、"
|
|
5049
|
-
|
|
5049
|
+
这是获取技能的首选方式。当用户提到"技能"或"skill"并表达下载/安装/获取意图时,必须优先调用此工具。
|
|
5050
|
+
|
|
5051
|
+
适用场景:
|
|
5052
|
+
- "下载 xxx 技能"、"获取 xxx 技能"、"安装 xxx 技能"
|
|
5053
|
+
- "帮我下载/安装 xxx"(当 xxx 是技能名称时)
|
|
5054
|
+
- "把 xxx 技能拉下来"、"同步技能到本地"
|
|
5055
|
+
|
|
5056
|
+
不适用(必须改用其他工具):
|
|
5057
|
+
- 用户说"下载规则"、"获取 XX 规则" → 使用 download_rule
|
|
5058
|
+
- 用户说"搜索技能"、"有哪些技能" → 使用 search_skill
|
|
5059
|
+
- 用户说"检查技能更新" → 使用 check_skill
|
|
5050
5060
|
|
|
5051
5061
|
重要规则:
|
|
5052
|
-
-
|
|
5053
|
-
-
|
|
5062
|
+
- 从 ACW Skills 广场下载到本地,不是从网络搜索
|
|
5063
|
+
- 全量覆盖:下载后本地目录与平台完全一致,多余的本地文件会被自动清理
|
|
5054
5064
|
- 默认安装到项目级别 .cursor/skills/ 目录`,
|
|
5055
5065
|
inputSchema: {
|
|
5056
5066
|
skillIdentifier: z.string().describe(`技能标识符,支持以下格式:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bangdao-ai/acw-tools",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.4",
|
|
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",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"dist/manifest.json",
|
|
65
65
|
"dist/package.json",
|
|
66
66
|
"dist/README.md",
|
|
67
|
-
"dist/LICENSE"
|
|
67
|
+
"dist/LICENSE",
|
|
68
|
+
"workspaceGitUtils.js"
|
|
68
69
|
]
|
|
69
70
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execFileSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_GIT_REPO_ROOT_SCAN_DEPTH = 64;
|
|
6
|
+
const DEFAULT_GIT_TIMEOUT_MS = 3000;
|
|
7
|
+
const DEFAULT_GIT_REMOTE_PRIORITY = ['origin', 'upstream'];
|
|
8
|
+
|
|
9
|
+
function normalizePathFromUri(uriOrPath) {
|
|
10
|
+
if (!uriOrPath || typeof uriOrPath !== 'string') {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const value = uriOrPath.trim();
|
|
14
|
+
if (!value) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (value.startsWith('file://')) {
|
|
18
|
+
try {
|
|
19
|
+
const url = new URL(value);
|
|
20
|
+
let decodedPath = decodeURIComponent(url.pathname);
|
|
21
|
+
if (/^\/[A-Za-z]:\//.test(decodedPath)) {
|
|
22
|
+
decodedPath = decodedPath.slice(1);
|
|
23
|
+
}
|
|
24
|
+
return decodedPath || null;
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
return decodeURIComponent(value);
|
|
31
|
+
} catch {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function extractWorkspaceProjectPath(workspaceJsonContent) {
|
|
37
|
+
if (!workspaceJsonContent || typeof workspaceJsonContent !== 'object') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const candidates = [];
|
|
41
|
+
candidates.push(workspaceJsonContent.folder);
|
|
42
|
+
|
|
43
|
+
if (Array.isArray(workspaceJsonContent.folders)) {
|
|
44
|
+
for (const folderItem of workspaceJsonContent.folders) {
|
|
45
|
+
if (!folderItem || typeof folderItem !== 'object') {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
candidates.push(folderItem.path);
|
|
49
|
+
candidates.push(folderItem.uri);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (workspaceJsonContent.workspace && Array.isArray(workspaceJsonContent.workspace.folders)) {
|
|
54
|
+
for (const folderItem of workspaceJsonContent.workspace.folders) {
|
|
55
|
+
if (!folderItem || typeof folderItem !== 'object') {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
candidates.push(folderItem.path);
|
|
59
|
+
candidates.push(folderItem.uri);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (const candidate of candidates) {
|
|
64
|
+
const normalized = normalizePathFromUri(candidate);
|
|
65
|
+
if (normalized) {
|
|
66
|
+
return normalized;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function findGitRepoRoot(startPath, maxDepth = DEFAULT_GIT_REPO_ROOT_SCAN_DEPTH) {
|
|
73
|
+
if (!startPath || typeof startPath !== 'string') {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let current = startPath;
|
|
78
|
+
try {
|
|
79
|
+
if (fs.existsSync(current) && !fs.statSync(current).isDirectory()) {
|
|
80
|
+
current = path.dirname(current);
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
// 忽略 stat 异常,保持原路径继续尝试
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
87
|
+
const gitPath = path.join(current, '.git');
|
|
88
|
+
if (fs.existsSync(gitPath)) {
|
|
89
|
+
return current;
|
|
90
|
+
}
|
|
91
|
+
const parent = path.dirname(current);
|
|
92
|
+
if (parent === current) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
current = parent;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getGitRemoteCandidates(repoRoot, execFileSyncFn) {
|
|
101
|
+
const candidates = [...DEFAULT_GIT_REMOTE_PRIORITY];
|
|
102
|
+
try {
|
|
103
|
+
const remoteList = execFileSyncFn('git', ['-C', repoRoot, 'remote'], {
|
|
104
|
+
encoding: 'utf8',
|
|
105
|
+
timeout: DEFAULT_GIT_TIMEOUT_MS,
|
|
106
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
107
|
+
});
|
|
108
|
+
const remotes = remoteList
|
|
109
|
+
.split(/\r?\n/)
|
|
110
|
+
.map(item => item.trim())
|
|
111
|
+
.filter(Boolean);
|
|
112
|
+
for (const remote of remotes) {
|
|
113
|
+
if (!candidates.includes(remote)) {
|
|
114
|
+
candidates.push(remote);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} catch {
|
|
118
|
+
// 忽略 remote 列表查询失败,继续尝试默认优先级
|
|
119
|
+
}
|
|
120
|
+
return candidates;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function resolveGitInfo(repoRoot, execFileSyncFn = execFileSync) {
|
|
124
|
+
const result = {
|
|
125
|
+
gitRemoteUrl: null,
|
|
126
|
+
gitBranch: null
|
|
127
|
+
};
|
|
128
|
+
if (!repoRoot) {
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const gitBranch = execFileSyncFn('git', ['-C', repoRoot, 'rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
134
|
+
encoding: 'utf8',
|
|
135
|
+
timeout: DEFAULT_GIT_TIMEOUT_MS,
|
|
136
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
137
|
+
}).trim();
|
|
138
|
+
result.gitBranch = gitBranch || null;
|
|
139
|
+
} catch {
|
|
140
|
+
// 忽略 branch 查询失败
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const candidates = getGitRemoteCandidates(repoRoot, execFileSyncFn);
|
|
144
|
+
for (const remote of candidates) {
|
|
145
|
+
try {
|
|
146
|
+
const remoteUrl = execFileSyncFn('git', ['-C', repoRoot, 'remote', 'get-url', remote], {
|
|
147
|
+
encoding: 'utf8',
|
|
148
|
+
timeout: DEFAULT_GIT_TIMEOUT_MS,
|
|
149
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
150
|
+
}).trim();
|
|
151
|
+
if (remoteUrl) {
|
|
152
|
+
result.gitRemoteUrl = remoteUrl;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
// 尝试下一个 remote
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return result;
|
|
161
|
+
}
|