jjb-cmd 2.5.7 → 2.5.9
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/package.json +1 -1
- package/src/ai-pull.js +1 -711
- package/src/auth.js +1 -71
- package/src/code-optimization.js +1 -46
- package/src/config.js +1 -122
- package/src/crypto-utils.js +1 -183
- package/src/password-input.js +1 -79
- package/src/publish.js +1 -307
- package/src/push.js +1 -417
- package/src/rm-rf.js +1 -49
- package/src/utils.js +1 -228
- package/SECURITY.md +0 -71
- package/build.js +0 -20
- package/obf.config.json +0 -3
package/src/ai-pull.js
CHANGED
|
@@ -1,711 +1 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const os = require('os');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const child_process = require('child_process');
|
|
5
|
-
|
|
6
|
-
// Cursor user rules SQLite 数据库路径
|
|
7
|
-
// Windows: C:\Users\<username>\AppData\Roaming\Cursor\User\globalStorage\state.vscdb
|
|
8
|
-
const CURSOR_DB_PATH = path.join(
|
|
9
|
-
os.homedir(),
|
|
10
|
-
'AppData',
|
|
11
|
-
'Roaming',
|
|
12
|
-
'Cursor',
|
|
13
|
-
'User',
|
|
14
|
-
'globalStorage',
|
|
15
|
-
'state.vscdb'
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
// Git 仓库地址
|
|
19
|
-
const AI_REPO_URL = 'http://192.168.1.242:10985/root/jjb-ai.git';
|
|
20
|
-
// Git 分支/标签(默认值)
|
|
21
|
-
const DEFAULT_BRANCH = 'v_2.0.0';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 删除目录(回调方式,使用递归删除)
|
|
25
|
-
*/
|
|
26
|
-
function deleteDir(dirPath, callback) {
|
|
27
|
-
if (!fs.existsSync(dirPath)) {
|
|
28
|
-
callback && callback();
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 递归删除目录和文件
|
|
33
|
-
function deleteRecursive(dir) {
|
|
34
|
-
if (!fs.existsSync(dir)) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
const files = fs.readdirSync(dir);
|
|
40
|
-
for (let i = 0; i < files.length; i++) {
|
|
41
|
-
const file = files[i];
|
|
42
|
-
const curPath = path.join(dir, file);
|
|
43
|
-
const stat = fs.statSync(curPath);
|
|
44
|
-
|
|
45
|
-
if (stat.isDirectory()) {
|
|
46
|
-
deleteRecursive(curPath);
|
|
47
|
-
// 删除空目录
|
|
48
|
-
try {
|
|
49
|
-
fs.rmdirSync(curPath);
|
|
50
|
-
} catch (e) {
|
|
51
|
-
// 忽略错误,可能目录不为空
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
try {
|
|
55
|
-
fs.unlinkSync(curPath);
|
|
56
|
-
} catch (e) {
|
|
57
|
-
// 忽略删除文件错误
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// 最后删除根目录
|
|
63
|
-
try {
|
|
64
|
-
fs.rmdirSync(dir);
|
|
65
|
-
} catch (e) {
|
|
66
|
-
// 忽略错误,可能目录不为空或正在使用
|
|
67
|
-
}
|
|
68
|
-
} catch (e) {
|
|
69
|
-
// 忽略错误
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
deleteRecursive(dirPath);
|
|
74
|
-
|
|
75
|
-
// 延迟回调,确保删除完成
|
|
76
|
-
setTimeout(() => {
|
|
77
|
-
callback && callback();
|
|
78
|
-
}, 300);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* 复制文件夹(回调方式,改进错误处理)
|
|
83
|
-
*/
|
|
84
|
-
function copyFolder(srcDir, tarDir, callback) {
|
|
85
|
-
if (!fs.existsSync(srcDir)) {
|
|
86
|
-
callback && callback(new Error(`源目录不存在: ${srcDir}`));
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// 确保目标目录存在
|
|
91
|
-
if (!fs.existsSync(tarDir)) {
|
|
92
|
-
try {
|
|
93
|
-
fs.mkdirSync(tarDir, { recursive: true });
|
|
94
|
-
} catch (e) {
|
|
95
|
-
callback && callback(e);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// 使用改进的复制函数
|
|
101
|
-
copyFolderRecursive(srcDir, tarDir, callback);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 递归复制文件夹(带错误处理)
|
|
106
|
-
*/
|
|
107
|
-
function copyFolderRecursive(srcDir, tarDir, callback) {
|
|
108
|
-
if (!fs.existsSync(srcDir)) {
|
|
109
|
-
callback && callback(new Error(`源目录不存在: ${srcDir}`));
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
try {
|
|
114
|
-
const files = fs.readdirSync(srcDir);
|
|
115
|
-
let completed = 0;
|
|
116
|
-
let hasError = false;
|
|
117
|
-
|
|
118
|
-
if (files.length === 0) {
|
|
119
|
-
callback && callback();
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
files.forEach((file) => {
|
|
124
|
-
const srcPath = path.join(srcDir, file);
|
|
125
|
-
const tarPath = path.join(tarDir, file);
|
|
126
|
-
|
|
127
|
-
try {
|
|
128
|
-
const stat = fs.statSync(srcPath);
|
|
129
|
-
|
|
130
|
-
if (stat.isDirectory()) {
|
|
131
|
-
// 确保目标目录存在
|
|
132
|
-
if (!fs.existsSync(tarPath)) {
|
|
133
|
-
fs.mkdirSync(tarPath, { recursive: true });
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
copyFolderRecursive(srcPath, tarPath, (err) => {
|
|
137
|
-
completed++;
|
|
138
|
-
if (err && !hasError) {
|
|
139
|
-
hasError = true;
|
|
140
|
-
console.log(`【Warning】:复制目录失败 ${srcPath}: ${err.message}`);
|
|
141
|
-
}
|
|
142
|
-
if (completed === files.length) {
|
|
143
|
-
callback && callback(hasError ? new Error('部分文件复制失败') : null);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
} else {
|
|
147
|
-
// 复制文件,带重试机制
|
|
148
|
-
copyFileWithRetry(srcPath, tarPath, 3, (err) => {
|
|
149
|
-
completed++;
|
|
150
|
-
if (err && !hasError) {
|
|
151
|
-
hasError = true;
|
|
152
|
-
console.log(`【Warning】:复制文件失败 ${srcPath}: ${err.message}`);
|
|
153
|
-
}
|
|
154
|
-
if (completed === files.length) {
|
|
155
|
-
callback && callback(hasError ? new Error('部分文件复制失败') : null);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
} catch (e) {
|
|
160
|
-
completed++;
|
|
161
|
-
if (!hasError) {
|
|
162
|
-
hasError = true;
|
|
163
|
-
console.log(`【Warning】:处理文件失败 ${srcPath}: ${e.message}`);
|
|
164
|
-
}
|
|
165
|
-
if (completed === files.length) {
|
|
166
|
-
callback && callback(hasError ? new Error('部分文件复制失败') : null);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
} catch (e) {
|
|
171
|
-
callback && callback(e);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* 复制文件(带重试机制)
|
|
177
|
-
*/
|
|
178
|
-
function copyFileWithRetry(srcPath, tarPath, retries, callback) {
|
|
179
|
-
if (retries <= 0) {
|
|
180
|
-
callback && callback(new Error(`复制文件失败,已重试多次: ${srcPath}`));
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// 确保目标目录存在
|
|
185
|
-
const tarDir = path.dirname(tarPath);
|
|
186
|
-
if (!fs.existsSync(tarDir)) {
|
|
187
|
-
try {
|
|
188
|
-
fs.mkdirSync(tarDir, { recursive: true });
|
|
189
|
-
} catch (e) {
|
|
190
|
-
callback && callback(e);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const rs = fs.createReadStream(srcPath);
|
|
196
|
-
const ws = fs.createWriteStream(tarPath);
|
|
197
|
-
|
|
198
|
-
rs.on('error', (err) => {
|
|
199
|
-
callback && callback(err);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
ws.on('error', (err) => {
|
|
203
|
-
// 如果是文件被占用或其他临时错误,尝试重试
|
|
204
|
-
if (retries > 1 && (err.code === 'EBUSY' || err.code === 'EPERM' || err.code === 'EACCES')) {
|
|
205
|
-
setTimeout(() => {
|
|
206
|
-
copyFileWithRetry(srcPath, tarPath, retries - 1, callback);
|
|
207
|
-
}, 100);
|
|
208
|
-
} else {
|
|
209
|
-
callback && callback(err);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
ws.on('close', () => {
|
|
214
|
-
callback && callback();
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
rs.pipe(ws);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
module.exports = (branch) => {
|
|
221
|
-
const root_path = path.resolve('./');
|
|
222
|
-
const tmpDir = os.tmpdir();
|
|
223
|
-
const cloneDir = path.join(tmpDir, 'jjb-ai-temp');
|
|
224
|
-
|
|
225
|
-
// 使用传入的分支参数,如果没有则使用默认值
|
|
226
|
-
const targetBranch = branch || DEFAULT_BRANCH;
|
|
227
|
-
|
|
228
|
-
console.log('【jjb-cmd ai-pull】:开始执行...');
|
|
229
|
-
console.log(`【分支】:${targetBranch}`);
|
|
230
|
-
|
|
231
|
-
// 步骤1: 拉取或更新仓库代码
|
|
232
|
-
console.log(`步骤1: 正在拉取 jjb-ai 仓库代码(分支: ${targetBranch})...`);
|
|
233
|
-
|
|
234
|
-
// 如果临时目录已存在,先删除
|
|
235
|
-
deleteDir(cloneDir, () => {
|
|
236
|
-
try {
|
|
237
|
-
// 克隆仓库指定分支/标签
|
|
238
|
-
child_process.execSync(`git clone -b ${targetBranch} ${AI_REPO_URL} "${cloneDir}"`, {
|
|
239
|
-
stdio: 'inherit',
|
|
240
|
-
cwd: tmpDir
|
|
241
|
-
});
|
|
242
|
-
console.log(`✓ 仓库代码拉取成功(分支: ${targetBranch})`);
|
|
243
|
-
|
|
244
|
-
// 步骤2: 将仓库 admin 下所有子文件夹同步到当前项目 .cursor/(与 admin 同名的子目录)
|
|
245
|
-
console.log('步骤2: 正在复制 admin 下的文件夹到 .cursor/...');
|
|
246
|
-
const adminPath = path.join(cloneDir, 'admin');
|
|
247
|
-
const cursorDir = path.join(root_path, '.cursor');
|
|
248
|
-
|
|
249
|
-
if (!fs.existsSync(adminPath)) {
|
|
250
|
-
console.log('【Warning】:仓库中未找到 admin 文件夹');
|
|
251
|
-
step3();
|
|
252
|
-
} else {
|
|
253
|
-
let subdirs;
|
|
254
|
-
try {
|
|
255
|
-
subdirs = fs.readdirSync(adminPath).filter((name) => {
|
|
256
|
-
const p = path.join(adminPath, name);
|
|
257
|
-
try {
|
|
258
|
-
return fs.statSync(p).isDirectory();
|
|
259
|
-
} catch (e) {
|
|
260
|
-
return false;
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
} catch (e) {
|
|
264
|
-
console.error('【Error】:读取 admin 目录失败', e.message);
|
|
265
|
-
cleanupAndExit(1);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (subdirs.length === 0) {
|
|
270
|
-
console.log('【Warning】:admin 下没有子文件夹可同步');
|
|
271
|
-
step3();
|
|
272
|
-
} else {
|
|
273
|
-
try {
|
|
274
|
-
if (!fs.existsSync(cursorDir)) {
|
|
275
|
-
fs.mkdirSync(cursorDir, { recursive: true });
|
|
276
|
-
}
|
|
277
|
-
} catch (e) {
|
|
278
|
-
console.error('【Error】:创建 .cursor 目录失败', e.message);
|
|
279
|
-
cleanupAndExit(1);
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function copyAdminDirAt(i) {
|
|
284
|
-
if (i >= subdirs.length) {
|
|
285
|
-
console.log(`✓ 已将 admin 下 ${subdirs.length} 个文件夹复制到 .cursor/(${subdirs.join(', ')})`);
|
|
286
|
-
step3();
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const name = subdirs[i];
|
|
290
|
-
const srcPath = path.join(adminPath, name);
|
|
291
|
-
const destPath = path.join(cursorDir, name);
|
|
292
|
-
const afterCopy = (err) => {
|
|
293
|
-
if (err) {
|
|
294
|
-
console.error(`【Error】:复制 admin/${name} 失败`, err.message);
|
|
295
|
-
cleanupAndExit(1);
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
copyAdminDirAt(i + 1);
|
|
299
|
-
};
|
|
300
|
-
if (fs.existsSync(destPath)) {
|
|
301
|
-
deleteDir(destPath, () => {
|
|
302
|
-
copyFolder(srcPath, destPath, afterCopy);
|
|
303
|
-
});
|
|
304
|
-
} else {
|
|
305
|
-
copyFolder(srcPath, destPath, afterCopy);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
copyAdminDirAt(0);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
} catch (error) {
|
|
313
|
-
console.error('【Error】:拉取仓库失败', error.message);
|
|
314
|
-
cleanupAndExit(1);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// 步骤3: 将 admin/rules/PROJECT.md 写入 Cursor user rules (SQLite 数据库)
|
|
319
|
-
function step3() {
|
|
320
|
-
console.log('步骤3: 正在更新 Cursor user rules (SQLite 数据库)...');
|
|
321
|
-
const projectRulesPath = path.join(cloneDir, 'admin', 'rules', 'PROJECT.md');
|
|
322
|
-
|
|
323
|
-
try {
|
|
324
|
-
if (!fs.existsSync(projectRulesPath)) {
|
|
325
|
-
console.log('【Warning】:仓库中未找到 admin/rules/PROJECT.md 文件');
|
|
326
|
-
step4();
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// 读取 PROJECT.md 内容
|
|
331
|
-
const rulesContent = fs.readFileSync(projectRulesPath, 'utf8');
|
|
332
|
-
|
|
333
|
-
// 检查数据库文件是否存在
|
|
334
|
-
if (!fs.existsSync(CURSOR_DB_PATH)) {
|
|
335
|
-
console.log('【Warning】:Cursor 数据库文件不存在,可能 Cursor 未安装或路径不正确');
|
|
336
|
-
console.log(`【路径】:${CURSOR_DB_PATH}`);
|
|
337
|
-
console.log('【建议】:请确保已安装 Cursor 编辑器,或手动复制 admin/rules/PROJECT.md 内容');
|
|
338
|
-
step4();
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// 备份数据库文件
|
|
343
|
-
try {
|
|
344
|
-
const dbDir = path.dirname(CURSOR_DB_PATH);
|
|
345
|
-
const dbFileName = path.basename(CURSOR_DB_PATH);
|
|
346
|
-
|
|
347
|
-
// 查找所有备份文件
|
|
348
|
-
const files = fs.existsSync(dbDir) ? fs.readdirSync(dbDir) : [];
|
|
349
|
-
const backupFiles = files.filter(file =>
|
|
350
|
-
file.startsWith(dbFileName + '.backup.')
|
|
351
|
-
);
|
|
352
|
-
|
|
353
|
-
// 删除所有旧的备份文件
|
|
354
|
-
backupFiles.forEach(backupFile => {
|
|
355
|
-
try {
|
|
356
|
-
const backupFilePath = path.join(dbDir, backupFile);
|
|
357
|
-
fs.unlinkSync(backupFilePath);
|
|
358
|
-
console.log(`✓ 已删除旧备份文件: ${backupFile}`);
|
|
359
|
-
} catch (e) {
|
|
360
|
-
// 忽略删除错误
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
// 创建新的备份文件
|
|
365
|
-
const backupPath = CURSOR_DB_PATH + '.backup.' + Date.now();
|
|
366
|
-
fs.copyFileSync(CURSOR_DB_PATH, backupPath);
|
|
367
|
-
console.log(`✓ 已备份数据库文件到 ${path.basename(backupPath)}`);
|
|
368
|
-
} catch (e) {
|
|
369
|
-
console.log('【Warning】:备份数据库文件失败', e.message);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// 使用 better-sqlite3 或 sqlite3 更新数据库
|
|
373
|
-
try {
|
|
374
|
-
// 尝试使用 better-sqlite3 (同步 API,更简单)
|
|
375
|
-
let Database;
|
|
376
|
-
try {
|
|
377
|
-
Database = require('better-sqlite3');
|
|
378
|
-
} catch (e) {
|
|
379
|
-
// 如果 better-sqlite3 不存在,尝试使用 sqlite3
|
|
380
|
-
try {
|
|
381
|
-
const sqlite3 = require('sqlite3');
|
|
382
|
-
// sqlite3 是异步的,需要使用回调或 Promise
|
|
383
|
-
console.log(`【调试】:准备更新数据库,内容长度: ${rulesContent.length} 字符`);
|
|
384
|
-
|
|
385
|
-
const db = new sqlite3.Database(CURSOR_DB_PATH, (err) => {
|
|
386
|
-
if (err) {
|
|
387
|
-
console.error('【Error】:无法打开数据库', err.message);
|
|
388
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
389
|
-
step4();
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// 先查询是否存在该键
|
|
394
|
-
db.get("SELECT value, length(value) as len FROM ItemTable WHERE key = ?", ['aicontext.personalContext'], (err, row) => {
|
|
395
|
-
if (err) {
|
|
396
|
-
console.error('【Error】:查询数据库失败', err.message);
|
|
397
|
-
db.close();
|
|
398
|
-
step4();
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// 更新或插入数据
|
|
403
|
-
if (row) {
|
|
404
|
-
console.log(`【调试】:找到现有记录,当前长度: ${row.len} 字节`);
|
|
405
|
-
|
|
406
|
-
// 检查内容是否已经相同
|
|
407
|
-
let oldContent = '';
|
|
408
|
-
if (Buffer.isBuffer(row.value)) {
|
|
409
|
-
oldContent = row.value.toString('utf8');
|
|
410
|
-
} else {
|
|
411
|
-
oldContent = String(row.value);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
if (oldContent === rulesContent) {
|
|
415
|
-
console.log('✓ admin/rules/PROJECT.md 内容未变化,无需更新');
|
|
416
|
-
console.log('【提示】:请重启 Cursor 编辑器以使规则生效');
|
|
417
|
-
db.close();
|
|
418
|
-
step4();
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// 更新现有记录
|
|
423
|
-
db.run("UPDATE ItemTable SET value = ? WHERE key = ?", [rulesContent, 'aicontext.personalContext'], function(err) {
|
|
424
|
-
if (err) {
|
|
425
|
-
console.error('【Error】:更新数据库失败', err.message);
|
|
426
|
-
if (err.code === 'SQLITE_BUSY' || err.message.includes('locked')) {
|
|
427
|
-
console.error('【Error】:数据库被锁定,可能是 Cursor 正在使用');
|
|
428
|
-
}
|
|
429
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
430
|
-
db.close();
|
|
431
|
-
step4();
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
console.log(`【调试】:更新影响行数: ${this.changes}`);
|
|
436
|
-
|
|
437
|
-
if (this.changes === 0) {
|
|
438
|
-
console.error('【Error】:更新失败,影响行数为 0,可能数据库被锁定');
|
|
439
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
440
|
-
db.close();
|
|
441
|
-
step4();
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// 验证更新是否成功
|
|
446
|
-
db.get("SELECT value, length(value) as len FROM ItemTable WHERE key = ?", ['aicontext.personalContext'], (err, verifyRow) => {
|
|
447
|
-
if (err) {
|
|
448
|
-
console.error('【Error】:验证更新失败', err.message);
|
|
449
|
-
} else if (verifyRow && verifyRow.value) {
|
|
450
|
-
let verifyContent = '';
|
|
451
|
-
if (Buffer.isBuffer(verifyRow.value)) {
|
|
452
|
-
verifyContent = verifyRow.value.toString('utf8');
|
|
453
|
-
} else {
|
|
454
|
-
verifyContent = String(verifyRow.value);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
if (verifyContent === rulesContent) {
|
|
458
|
-
console.log(`✓ PROJECT.md 已更新到 Cursor user rules (${verifyRow.len} 字节)`);
|
|
459
|
-
// 显示前几行内容确认
|
|
460
|
-
const previewLines = verifyContent.split('\n').slice(0, 3).join('\n');
|
|
461
|
-
console.log(`【预览】:内容前3行:\n${previewLines}${verifyContent.split('\n').length > 3 ? '...' : ''}`);
|
|
462
|
-
} else {
|
|
463
|
-
console.error(`【Error】:更新后内容不匹配!`);
|
|
464
|
-
console.error(` 期望长度: ${rulesContent.length}, 实际长度: ${verifyContent.length}`);
|
|
465
|
-
console.error(` 期望前100字符: ${rulesContent.substring(0, 100)}`);
|
|
466
|
-
console.error(` 实际前100字符: ${verifyContent.substring(0, 100)}`);
|
|
467
|
-
}
|
|
468
|
-
} else {
|
|
469
|
-
console.error('【Error】:更新后验证失败,值为空');
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
console.log('【提示】:请重启 Cursor 编辑器以使规则生效');
|
|
473
|
-
db.close();
|
|
474
|
-
step4();
|
|
475
|
-
});
|
|
476
|
-
});
|
|
477
|
-
} else {
|
|
478
|
-
console.log('【调试】:记录不存在,将插入新记录');
|
|
479
|
-
// 插入新记录
|
|
480
|
-
db.run("INSERT INTO ItemTable (key, value) VALUES (?, ?)", ['aicontext.personalContext', rulesContent], function(err) {
|
|
481
|
-
if (err) {
|
|
482
|
-
console.error('【Error】:插入数据库失败', err.message);
|
|
483
|
-
if (err.code === 'SQLITE_BUSY' || err.message.includes('locked')) {
|
|
484
|
-
console.error('【Error】:数据库被锁定,可能是 Cursor 正在使用');
|
|
485
|
-
}
|
|
486
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
487
|
-
db.close();
|
|
488
|
-
step4();
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
console.log(`【调试】:插入结果,最后插入ID: ${this.lastInsertRowid}`);
|
|
493
|
-
|
|
494
|
-
if (!this.lastInsertRowid) {
|
|
495
|
-
console.error('【Error】:插入失败,未返回插入ID');
|
|
496
|
-
db.close();
|
|
497
|
-
step4();
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// 验证插入是否成功
|
|
502
|
-
db.get("SELECT value, length(value) as len FROM ItemTable WHERE key = ?", ['aicontext.personalContext'], (err, verifyRow) => {
|
|
503
|
-
if (err) {
|
|
504
|
-
console.error('【Error】:验证插入失败', err.message);
|
|
505
|
-
} else if (verifyRow && verifyRow.value) {
|
|
506
|
-
let verifyContent = '';
|
|
507
|
-
if (Buffer.isBuffer(verifyRow.value)) {
|
|
508
|
-
verifyContent = verifyRow.value.toString('utf8');
|
|
509
|
-
} else {
|
|
510
|
-
verifyContent = String(verifyRow.value);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (verifyContent === rulesContent) {
|
|
514
|
-
console.log(`✓ PROJECT.md 已添加到 Cursor user rules (${verifyRow.len} 字节)`);
|
|
515
|
-
// 显示前几行内容确认
|
|
516
|
-
const previewLines = verifyContent.split('\n').slice(0, 3).join('\n');
|
|
517
|
-
console.log(`【预览】:内容前3行:\n${previewLines}${verifyContent.split('\n').length > 3 ? '...' : ''}`);
|
|
518
|
-
} else {
|
|
519
|
-
console.error(`【Error】:插入后内容不匹配!`);
|
|
520
|
-
console.error(` 期望长度: ${rulesContent.length}, 实际长度: ${verifyContent.length}`);
|
|
521
|
-
}
|
|
522
|
-
} else {
|
|
523
|
-
console.error('【Error】:插入后验证失败,值为空');
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
console.log('【提示】:请重启 Cursor 编辑器以使规则生效');
|
|
527
|
-
db.close();
|
|
528
|
-
step4();
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
});
|
|
533
|
-
});
|
|
534
|
-
return; // 异步操作,提前返回
|
|
535
|
-
} catch (e2) {
|
|
536
|
-
console.error('【Error】:未找到 SQLite 模块 (better-sqlite3 或 sqlite3)');
|
|
537
|
-
console.log('【建议】:请运行 npm install better-sqlite3 或 npm install sqlite3');
|
|
538
|
-
console.log('【或者】:使用命令行工具手动更新数据库');
|
|
539
|
-
step4();
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// 使用 better-sqlite3 (同步 API)
|
|
545
|
-
const db = new Database(CURSOR_DB_PATH, { readonly: false });
|
|
546
|
-
|
|
547
|
-
try {
|
|
548
|
-
console.log(`【调试】:准备更新数据库,内容长度: ${rulesContent.length} 字符`);
|
|
549
|
-
|
|
550
|
-
// 先查询是否存在该键
|
|
551
|
-
const row = db.prepare("SELECT value, length(value) as len FROM ItemTable WHERE key = ?").get('aicontext.personalContext');
|
|
552
|
-
|
|
553
|
-
if (row) {
|
|
554
|
-
console.log(`【调试】:找到现有记录,当前长度: ${row.len} 字节`);
|
|
555
|
-
|
|
556
|
-
// 检查内容是否已经相同
|
|
557
|
-
let oldContent = '';
|
|
558
|
-
if (Buffer.isBuffer(row.value)) {
|
|
559
|
-
oldContent = row.value.toString('utf8');
|
|
560
|
-
} else {
|
|
561
|
-
oldContent = String(row.value);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
if (oldContent === rulesContent) {
|
|
565
|
-
console.log('✓ admin/rules/PROJECT.md 内容未变化,无需更新');
|
|
566
|
-
console.log('【提示】:请重启 Cursor 编辑器以使规则生效');
|
|
567
|
-
db.close();
|
|
568
|
-
step4();
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
// 更新现有记录
|
|
573
|
-
const updateStmt = db.prepare("UPDATE ItemTable SET value = ? WHERE key = ?");
|
|
574
|
-
const result = updateStmt.run(rulesContent, 'aicontext.personalContext');
|
|
575
|
-
console.log(`【调试】:更新影响行数: ${result.changes}`);
|
|
576
|
-
|
|
577
|
-
if (result.changes === 0) {
|
|
578
|
-
console.error('【Error】:更新失败,影响行数为 0,可能数据库被锁定');
|
|
579
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
580
|
-
db.close();
|
|
581
|
-
step4();
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// 验证更新是否成功
|
|
586
|
-
const verifyRow = db.prepare("SELECT value, length(value) as len FROM ItemTable WHERE key = ?").get('aicontext.personalContext');
|
|
587
|
-
if (verifyRow && verifyRow.value) {
|
|
588
|
-
let verifyContent = '';
|
|
589
|
-
if (Buffer.isBuffer(verifyRow.value)) {
|
|
590
|
-
verifyContent = verifyRow.value.toString('utf8');
|
|
591
|
-
} else {
|
|
592
|
-
verifyContent = String(verifyRow.value);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
if (verifyContent === rulesContent) {
|
|
596
|
-
console.log(`✓ PROJECT.md 已更新到 Cursor user rules (${verifyRow.len} 字节)`);
|
|
597
|
-
// 显示前几行内容确认
|
|
598
|
-
const previewLines = verifyContent.split('\n').slice(0, 3).join('\n');
|
|
599
|
-
console.log(`【预览】:内容前3行:\n${previewLines}${verifyContent.split('\n').length > 3 ? '...' : ''}`);
|
|
600
|
-
} else {
|
|
601
|
-
console.error(`【Error】:更新后内容不匹配!`);
|
|
602
|
-
console.error(` 期望长度: ${rulesContent.length}, 实际长度: ${verifyContent.length}`);
|
|
603
|
-
console.error(` 期望前100字符: ${rulesContent.substring(0, 100)}`);
|
|
604
|
-
console.error(` 实际前100字符: ${verifyContent.substring(0, 100)}`);
|
|
605
|
-
}
|
|
606
|
-
} else {
|
|
607
|
-
console.error('【Error】:更新后验证失败,值为空');
|
|
608
|
-
}
|
|
609
|
-
} else {
|
|
610
|
-
console.log('【调试】:记录不存在,将插入新记录');
|
|
611
|
-
// 插入新记录
|
|
612
|
-
const insertStmt = db.prepare("INSERT INTO ItemTable (key, value) VALUES (?, ?)");
|
|
613
|
-
const result = insertStmt.run('aicontext.personalContext', rulesContent);
|
|
614
|
-
console.log(`【调试】:插入结果,最后插入ID: ${result.lastInsertRowid}`);
|
|
615
|
-
|
|
616
|
-
if (!result.lastInsertRowid) {
|
|
617
|
-
console.error('【Error】:插入失败,未返回插入ID');
|
|
618
|
-
db.close();
|
|
619
|
-
step4();
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
// 验证插入是否成功
|
|
624
|
-
const verifyRow = db.prepare("SELECT value, length(value) as len FROM ItemTable WHERE key = ?").get('aicontext.personalContext');
|
|
625
|
-
if (verifyRow && verifyRow.value) {
|
|
626
|
-
let verifyContent = '';
|
|
627
|
-
if (Buffer.isBuffer(verifyRow.value)) {
|
|
628
|
-
verifyContent = verifyRow.value.toString('utf8');
|
|
629
|
-
} else {
|
|
630
|
-
verifyContent = String(verifyRow.value);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
if (verifyContent === rulesContent) {
|
|
634
|
-
console.log(`✓ PROJECT.md 已添加到 Cursor user rules (${verifyRow.len} 字节)`);
|
|
635
|
-
// 显示前几行内容确认
|
|
636
|
-
const previewLines = verifyContent.split('\n').slice(0, 3).join('\n');
|
|
637
|
-
console.log(`【预览】:内容前3行:\n${previewLines}${verifyContent.split('\n').length > 3 ? '...' : ''}`);
|
|
638
|
-
} else {
|
|
639
|
-
console.error(`【Error】:插入后内容不匹配!`);
|
|
640
|
-
console.error(` 期望长度: ${rulesContent.length}, 实际长度: ${verifyContent.length}`);
|
|
641
|
-
}
|
|
642
|
-
} else {
|
|
643
|
-
console.error('【Error】:插入后验证失败,值为空');
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
console.log('【提示】:请重启 Cursor 编辑器以使规则生效');
|
|
648
|
-
} catch (dbError) {
|
|
649
|
-
console.error('【Error】:操作数据库失败', dbError.message);
|
|
650
|
-
if (dbError.code === 'SQLITE_BUSY' || dbError.message.includes('locked')) {
|
|
651
|
-
console.error('【Error】:数据库被锁定,可能是 Cursor 正在使用');
|
|
652
|
-
}
|
|
653
|
-
console.error('【Error】:错误堆栈', dbError.stack);
|
|
654
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
655
|
-
} finally {
|
|
656
|
-
db.close();
|
|
657
|
-
}
|
|
658
|
-
} catch (dbError) {
|
|
659
|
-
console.error('【Error】:无法打开数据库', dbError.message);
|
|
660
|
-
console.log('【建议】:请关闭 Cursor 编辑器后重试');
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
step4();
|
|
664
|
-
} catch (error) {
|
|
665
|
-
console.error('【Error】:处理 admin/rules/PROJECT.md 失败', error.message);
|
|
666
|
-
console.log('【Warning】:可能 Cursor 未安装或路径不正确,请手动复制 admin/rules/PROJECT.md 内容');
|
|
667
|
-
step4();
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
// 步骤4: 检查并更新 .gitignore
|
|
672
|
-
function step4() {
|
|
673
|
-
console.log('步骤4: 正在检查 .gitignore 文件...');
|
|
674
|
-
const gitignorePath = path.join(root_path, '.gitignore');
|
|
675
|
-
|
|
676
|
-
try {
|
|
677
|
-
if (fs.existsSync(gitignorePath)) {
|
|
678
|
-
let gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
679
|
-
const cursorIgnorePattern = /^\.cursor\/?\s*$/m;
|
|
680
|
-
|
|
681
|
-
if (!cursorIgnorePattern.test(gitignoreContent)) {
|
|
682
|
-
// 如果文件末尾没有换行,先添加换行
|
|
683
|
-
if (!gitignoreContent.endsWith('\n')) {
|
|
684
|
-
gitignoreContent += '\n';
|
|
685
|
-
}
|
|
686
|
-
gitignoreContent += '.cursor/\n';
|
|
687
|
-
fs.writeFileSync(gitignorePath, gitignoreContent, 'utf8');
|
|
688
|
-
console.log('✓ 已在 .gitignore 中添加 .cursor/ 忽略规则');
|
|
689
|
-
} else {
|
|
690
|
-
console.log('✓ .gitignore 中已存在 .cursor 忽略规则');
|
|
691
|
-
}
|
|
692
|
-
} else {
|
|
693
|
-
// 如果 .gitignore 不存在,创建它
|
|
694
|
-
fs.writeFileSync(gitignorePath, '.cursor/\n', 'utf8');
|
|
695
|
-
console.log('✓ 已创建 .gitignore 并添加 .cursor/ 忽略规则');
|
|
696
|
-
}
|
|
697
|
-
} catch (error) {
|
|
698
|
-
console.error('【Error】:更新 .gitignore 失败', error.message);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
cleanupAndExit(0);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
// 清理临时目录并退出
|
|
705
|
-
function cleanupAndExit(exitCode) {
|
|
706
|
-
deleteDir(cloneDir, () => {
|
|
707
|
-
console.log('【jjb-cmd ai-pull】:执行完成!');
|
|
708
|
-
process.exit(exitCode);
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
|
-
};
|
|
1
|
+
const a0_0x39adc1=a0_0x3bd1;function a0_0x28d8(){const _0x3616c0=['state.vscdb','5613972yMspCn','lastInsertRowid','部分文件复制失败','【Warning】:','✓\x20已将\x20','源目录不存在:\x20','admin','9667098mVAVjH','步骤3:\x20正在更新\x20Cursor\x20user\x20rules\x20(SQLite\x20数据库)...','statSync','32296DLTFIk','get','.config','【Error】:更新后内容不匹配!','Library','filter','【Error】:数据库被锁定,可能是\x20Cursor\x20正在使用','【调试】:找到现有记录,当前长度:\x20','Cursor','\x20\x20实际前100字符:\x20','【Error】:插入失败,未返回插入ID','PROJECT.md',',\x20实际长度:\x20','【Error】:验证插入失败','.gitignore','88551dNkmOc','【Error】:处理\x20admin/rules/PROJECT.md\x20失败','execSync','【提示】:请重启\x20Cursor\x20编辑器以使规则生效','run','changes','✓\x20PROJECT.md\x20已添加到\x20Cursor\x20user\x20rules\x20(','✓\x20admin/rules/PROJECT.md\x20内容未变化,无需更新','26EXYGit','forEach','【Error】:复制\x20','复制文件失败,已重试多次:\x20','\x20字节','Database','rmdirSync','split','now','prepare','startsWith','【调试】:准备更新数据库,内容长度:\x20','UPDATE\x20ItemTable\x20SET\x20value\x20=\x20?\x20WHERE\x20key\x20=\x20?','pipe','【Error】:未找到\x20SQLite\x20模块\x20(better-sqlite3\x20或\x20sqlite3)','【分支】:','EBUSY','.cursor','.backup.','rules','createReadStream','SELECT\x20value,\x20length(value)\x20as\x20len\x20FROM\x20ItemTable\x20WHERE\x20key\x20=\x20?','.cursor/\x0a','dirname','EACCES','locked','aicontext.personalContext','INSERT\x20INTO\x20ItemTable\x20(key,\x20value)\x20VALUES\x20(?,\x20?)','【调试】:插入结果,最后插入ID:\x20','AppData','【Warning】:处理文件失败\x20','✓\x20已创建\x20.gitignore\x20并添加\x20.cursor/\x20忽略规则','close','test','slice','【Warning】:备份数据库文件失败','...','User','【Error】:验证更新失败','【Warning】:复制文件失败\x20','【Warning】:仓库中未找到\x20admin/rules/PROJECT.md\x20文件','✓\x20已在\x20.gitignore\x20中添加\x20.cursor/\x20忽略规则','【jjb-cmd\x20ai-pull】:执行完成!','【Warning】:可能\x20Cursor\x20未安装或路径不正确,请手动复制\x20admin/rules/PROJECT.md\x20内容','path','【调试】:更新影响行数:\x20','971141cYakzP','better-sqlite3','EPERM','createWriteStream','Application\x20Support','git\x20clone\x20-b\x20','\x20\x20期望前100字符:\x20','\x20失败','readFileSync','29645gXSIOs','message','len','【Error】:拉取仓库失败','✓\x20已删除旧备份文件:\x20','【Error】:插入后验证失败,值为空','platform','isBuffer','endsWith','【Error】:创建\x20.cursor\x20目录失败','✓\x20.gitignore\x20中已存在\x20.cursor\x20忽略规则','361605keKfwM','isDirectory','readdirSync','error','【预览】:内容前3行:\x0a','substring','copyFileSync','code','【Error】:插入后内容不匹配!','utf8','【Error】:操作数据库失败','【建议】:请确保已安装\x20Cursor\x20编辑器,或手动复制\x20admin/rules/PROJECT.md\x20内容','toString','existsSync','includes','length','admin/.cursor','步骤4:\x20正在检查\x20.gitignore\x20文件...','mkdirSync','【jjb-cmd\x20ai-pull】:开始执行...','\x20\x20期望长度:\x20','SQLITE_BUSY','http://192.168.1.242:10985/root/jjb-ai.git',')...','join','8160UMnzYd','228gRKCjf','unlinkSync','tmpdir','【Error】:读取\x20','\x20目录失败','Roaming','log','v_2.0.0','basename','sqlite3','【调试】:记录不存在,将插入新记录','✓\x20已备份数据库文件到\x20','\x20字节)','value','【Error】:更新后验证失败,值为空','globalStorage','\x20字符','✓\x20PROJECT.md\x20已更新到\x20Cursor\x20user\x20rules\x20(','1424kXaCxQ','【建议】:请关闭\x20Cursor\x20编辑器后重试','【建议】:请运行\x20npm\x20install\x20better-sqlite3\x20或\x20npm\x20install\x20sqlite3','writeFileSync','\x20下没有子文件夹可同步'];a0_0x28d8=function(){return _0x3616c0;};return a0_0x28d8();}(function(_0x1e58e5,_0x571464){const _0x2dca5f=a0_0x3bd1,_0x22b1d9=_0x1e58e5();while(!![]){try{const _0x34f58d=parseInt(_0x2dca5f(0x15b))/0x1+parseInt(_0x2dca5f(0x12d))/0x2*(parseInt(_0x2dca5f(0x16f))/0x3)+parseInt(_0x2dca5f(0x1a1))/0x4+-parseInt(_0x2dca5f(0x164))/0x5*(parseInt(_0x2dca5f(0x189))/0x6)+parseInt(_0x2dca5f(0x1a8))/0x7+-parseInt(_0x2dca5f(0x19b))/0x8*(parseInt(_0x2dca5f(0x125))/0x9)+parseInt(_0x2dca5f(0x188))/0xa*(-parseInt(_0x2dca5f(0x1ab))/0xb);if(_0x34f58d===_0x571464)break;else _0x22b1d9['push'](_0x22b1d9['shift']());}catch(_0x46b377){_0x22b1d9['push'](_0x22b1d9['shift']());}}}(a0_0x28d8,0xe7fa7));const fs=require('fs'),os=require('os'),path=require(a0_0x39adc1(0x159)),child_process=require('child_process');function getCursorDbPath(){const _0x343e19=a0_0x39adc1,_0x5dfd85=os['homedir'](),_0x2ee6a6=os[_0x343e19(0x16a)]();if(_0x2ee6a6==='win32')return path[_0x343e19(0x187)](_0x5dfd85,_0x343e19(0x14a),_0x343e19(0x18e),_0x343e19(0x1b3),_0x343e19(0x152),_0x343e19(0x198),_0x343e19(0x1a0));else return _0x2ee6a6==='darwin'?path[_0x343e19(0x187)](_0x5dfd85,_0x343e19(0x1af),_0x343e19(0x15f),_0x343e19(0x1b3),_0x343e19(0x152),_0x343e19(0x198),_0x343e19(0x1a0)):path[_0x343e19(0x187)](_0x5dfd85,_0x343e19(0x1ad),'Cursor','User',_0x343e19(0x198),'state.vscdb');}const CURSOR_DB_PATH=getCursorDbPath(),AI_REPO_URL=a0_0x39adc1(0x185),DEFAULT_BRANCH=a0_0x39adc1(0x190);function deleteDir(_0x4c609c,_0x4ef2c1){if(!fs['existsSync'](_0x4c609c)){_0x4ef2c1&&_0x4ef2c1();return;}function _0x2b09a0(_0x239fee){const _0x53ec07=a0_0x3bd1;if(!fs[_0x53ec07(0x17c)](_0x239fee))return;try{const _0x74a9cd=fs[_0x53ec07(0x171)](_0x239fee);for(let _0x43dfb9=0x0;_0x43dfb9<_0x74a9cd[_0x53ec07(0x17e)];_0x43dfb9++){const _0x11b483=_0x74a9cd[_0x43dfb9],_0x2b6b88=path[_0x53ec07(0x187)](_0x239fee,_0x11b483),_0xb149c5=fs[_0x53ec07(0x1aa)](_0x2b6b88);if(_0xb149c5[_0x53ec07(0x170)]()){_0x2b09a0(_0x2b6b88);try{fs[_0x53ec07(0x133)](_0x2b6b88);}catch(_0x4ca58b){}}else try{fs[_0x53ec07(0x18a)](_0x2b6b88);}catch(_0x22a2f7){}}try{fs[_0x53ec07(0x133)](_0x239fee);}catch(_0x384d32){}}catch(_0x4ce3df){}}_0x2b09a0(_0x4c609c),setTimeout(()=>{_0x4ef2c1&&_0x4ef2c1();},0x12c);}function copyFolder(_0x45b6e0,_0x5d33d5,_0x119628){const _0x33a8de=a0_0x39adc1;if(!fs[_0x33a8de(0x17c)](_0x45b6e0)){_0x119628&&_0x119628(new Error(_0x33a8de(0x1a6)+_0x45b6e0));return;}if(!fs['existsSync'](_0x5d33d5))try{fs[_0x33a8de(0x181)](_0x5d33d5,{'recursive':!![]});}catch(_0x8cfd37){_0x119628&&_0x119628(_0x8cfd37);return;}copyFolderRecursive(_0x45b6e0,_0x5d33d5,_0x119628);}function a0_0x3bd1(_0x48eefa,_0x111ba1){_0x48eefa=_0x48eefa-0x125;const _0x28d82f=a0_0x28d8();let _0x3bd1b2=_0x28d82f[_0x48eefa];return _0x3bd1b2;}function copyFolderRecursive(_0x192325,_0x4aea90,_0xf9d679){const _0x18432e=a0_0x39adc1;if(!fs[_0x18432e(0x17c)](_0x192325)){_0xf9d679&&_0xf9d679(new Error(_0x18432e(0x1a6)+_0x192325));return;}try{const _0x1a115b=fs['readdirSync'](_0x192325);let _0xacc71d=0x0,_0x1c54d6=![];if(_0x1a115b['length']===0x0){_0xf9d679&&_0xf9d679();return;}_0x1a115b[_0x18432e(0x12e)](_0xd1fcd5=>{const _0x569e12=_0x18432e,_0x25635d=path[_0x569e12(0x187)](_0x192325,_0xd1fcd5),_0x3e6a56=path[_0x569e12(0x187)](_0x4aea90,_0xd1fcd5);try{const _0x563428=fs[_0x569e12(0x1aa)](_0x25635d);_0x563428[_0x569e12(0x170)]()?(!fs['existsSync'](_0x3e6a56)&&fs['mkdirSync'](_0x3e6a56,{'recursive':!![]}),copyFolderRecursive(_0x25635d,_0x3e6a56,_0x30c4df=>{const _0x958a9c=_0x569e12;_0xacc71d++,_0x30c4df&&!_0x1c54d6&&(_0x1c54d6=!![],console[_0x958a9c(0x18f)]('【Warning】:复制目录失败\x20'+_0x25635d+':\x20'+_0x30c4df['message'])),_0xacc71d===_0x1a115b['length']&&(_0xf9d679&&_0xf9d679(_0x1c54d6?new Error(_0x958a9c(0x1a3)):null));})):copyFileWithRetry(_0x25635d,_0x3e6a56,0x3,_0x1521cc=>{const _0x16d5a9=_0x569e12;_0xacc71d++,_0x1521cc&&!_0x1c54d6&&(_0x1c54d6=!![],console['log'](_0x16d5a9(0x154)+_0x25635d+':\x20'+_0x1521cc['message'])),_0xacc71d===_0x1a115b[_0x16d5a9(0x17e)]&&(_0xf9d679&&_0xf9d679(_0x1c54d6?new Error(_0x16d5a9(0x1a3)):null));});}catch(_0x173881){_0xacc71d++,!_0x1c54d6&&(_0x1c54d6=!![],console[_0x569e12(0x18f)](_0x569e12(0x14b)+_0x25635d+':\x20'+_0x173881[_0x569e12(0x165)])),_0xacc71d===_0x1a115b[_0x569e12(0x17e)]&&(_0xf9d679&&_0xf9d679(_0x1c54d6?new Error(_0x569e12(0x1a3)):null));}});}catch(_0x1f3c3b){_0xf9d679&&_0xf9d679(_0x1f3c3b);}}function copyFileWithRetry(_0x34b6b9,_0x355bad,_0x144367,_0xda4ff3){const _0x5da021=a0_0x39adc1;if(_0x144367<=0x0){_0xda4ff3&&_0xda4ff3(new Error(_0x5da021(0x130)+_0x34b6b9));return;}const _0x2a1fe0=path[_0x5da021(0x144)](_0x355bad);if(!fs[_0x5da021(0x17c)](_0x2a1fe0))try{fs[_0x5da021(0x181)](_0x2a1fe0,{'recursive':!![]});}catch(_0x4a7697){_0xda4ff3&&_0xda4ff3(_0x4a7697);return;}const _0x2ba6c2=fs[_0x5da021(0x141)](_0x34b6b9),_0x41b040=fs[_0x5da021(0x15e)](_0x355bad);_0x2ba6c2['on'](_0x5da021(0x172),_0x1bf24b=>{_0xda4ff3&&_0xda4ff3(_0x1bf24b);}),_0x41b040['on'](_0x5da021(0x172),_0x575124=>{const _0x31257b=_0x5da021;_0x144367>0x1&&(_0x575124[_0x31257b(0x176)]===_0x31257b(0x13d)||_0x575124[_0x31257b(0x176)]===_0x31257b(0x15d)||_0x575124[_0x31257b(0x176)]===_0x31257b(0x145))?setTimeout(()=>{copyFileWithRetry(_0x34b6b9,_0x355bad,_0x144367-0x1,_0xda4ff3);},0x64):_0xda4ff3&&_0xda4ff3(_0x575124);}),_0x41b040['on']('close',()=>{_0xda4ff3&&_0xda4ff3();}),_0x2ba6c2[_0x5da021(0x13a)](_0x41b040);}module['exports']=_0x14770d=>{const _0x3ccb40=a0_0x39adc1,_0x2a1c0d=path['resolve']('./'),_0x588d03=os[_0x3ccb40(0x18b)](),_0x5d6401=path[_0x3ccb40(0x187)](_0x588d03,'jjb-ai-temp'),_0x5dfac9=_0x14770d||DEFAULT_BRANCH;console[_0x3ccb40(0x18f)](_0x3ccb40(0x182)),console['log'](_0x3ccb40(0x13c)+_0x5dfac9),console[_0x3ccb40(0x18f)]('步骤1:\x20正在拉取\x20jjb-ai\x20仓库代码(分支:\x20'+_0x5dfac9+_0x3ccb40(0x186)),deleteDir(_0x5d6401,()=>{const _0x120af2=_0x3ccb40;try{child_process[_0x120af2(0x127)](_0x120af2(0x160)+_0x5dfac9+'\x20'+AI_REPO_URL+'\x20\x22'+_0x5d6401+'\x22',{'stdio':'inherit','cwd':_0x588d03}),console[_0x120af2(0x18f)]('✓\x20仓库代码拉取成功(分支:\x20'+_0x5dfac9+')'),console[_0x120af2(0x18f)]('步骤2:\x20正在复制\x20admin\x20内\x20Cursor\x20资源到\x20.cursor/...');const _0x26504d=path['join'](_0x5d6401,_0x120af2(0x1a7)),_0x1a6cce=path[_0x120af2(0x187)](_0x26504d,'.cursor'),_0x189b58=fs[_0x120af2(0x17c)](_0x1a6cce)?_0x1a6cce:_0x26504d,_0x36cf45=fs['existsSync'](_0x1a6cce)?_0x120af2(0x17f):_0x120af2(0x1a7),_0x3e1408=path[_0x120af2(0x187)](_0x2a1c0d,_0x120af2(0x13e));if(!fs['existsSync'](_0x26504d))console[_0x120af2(0x18f)]('【Warning】:仓库中未找到\x20admin\x20文件夹'),_0x149a36();else{let _0x44dce1;try{_0x44dce1=fs['readdirSync'](_0x189b58)['filter'](_0x514dde=>{const _0x597f07=_0x120af2,_0x427a4d=path[_0x597f07(0x187)](_0x189b58,_0x514dde);try{return fs['statSync'](_0x427a4d)[_0x597f07(0x170)]();}catch(_0x2ebe05){return![];}});}catch(_0x5660e9){console[_0x120af2(0x172)](_0x120af2(0x18c)+_0x36cf45+_0x120af2(0x18d),_0x5660e9[_0x120af2(0x165)]),_0x26fe46(0x1);return;}if(_0x44dce1['length']===0x0)console[_0x120af2(0x18f)](_0x120af2(0x1a4)+_0x36cf45+_0x120af2(0x19f)),_0x149a36();else{try{!fs[_0x120af2(0x17c)](_0x3e1408)&&fs['mkdirSync'](_0x3e1408,{'recursive':!![]});}catch(_0x73c519){console[_0x120af2(0x172)](_0x120af2(0x16d),_0x73c519[_0x120af2(0x165)]),_0x26fe46(0x1);return;}function _0x1b13ad(_0x462999){const _0x2ba769=_0x120af2;if(_0x462999>=_0x44dce1[_0x2ba769(0x17e)]){console['log'](_0x2ba769(0x1a5)+_0x36cf45+'\x20下\x20'+_0x44dce1[_0x2ba769(0x17e)]+'\x20个文件夹复制到\x20.cursor/('+_0x44dce1[_0x2ba769(0x187)](',\x20')+')'),_0x149a36();return;}const _0x2f0884=_0x44dce1[_0x462999],_0x29b79f=path[_0x2ba769(0x187)](_0x189b58,_0x2f0884),_0x400598=path['join'](_0x3e1408,_0x2f0884),_0xb8c4f1=_0x4d9e42=>{const _0x42fa19=_0x2ba769;if(_0x4d9e42){console['error'](_0x42fa19(0x12f)+_0x36cf45+'/'+_0x2f0884+_0x42fa19(0x162),_0x4d9e42[_0x42fa19(0x165)]),_0x26fe46(0x1);return;}_0x1b13ad(_0x462999+0x1);};fs[_0x2ba769(0x17c)](_0x400598)?deleteDir(_0x400598,()=>{copyFolder(_0x29b79f,_0x400598,_0xb8c4f1);}):copyFolder(_0x29b79f,_0x400598,_0xb8c4f1);}_0x1b13ad(0x0);}}}catch(_0x4c095a){console[_0x120af2(0x172)](_0x120af2(0x167),_0x4c095a[_0x120af2(0x165)]),_0x26fe46(0x1);}});function _0x149a36(){const _0x4801a6=_0x3ccb40;console['log'](_0x4801a6(0x1a9));const _0x1f10d6=path[_0x4801a6(0x187)](_0x5d6401,_0x4801a6(0x1a7),_0x4801a6(0x140),_0x4801a6(0x1b6));try{if(!fs['existsSync'](_0x1f10d6)){console[_0x4801a6(0x18f)](_0x4801a6(0x155)),_0x28eed2();return;}const _0x510511=fs[_0x4801a6(0x163)](_0x1f10d6,'utf8');if(!fs[_0x4801a6(0x17c)](CURSOR_DB_PATH)){console[_0x4801a6(0x18f)]('【Warning】:Cursor\x20数据库文件不存在,可能\x20Cursor\x20未安装或路径不正确'),console[_0x4801a6(0x18f)]('【路径】:'+CURSOR_DB_PATH),console[_0x4801a6(0x18f)](_0x4801a6(0x17a)),_0x28eed2();return;}try{const _0x1613d4=path['dirname'](CURSOR_DB_PATH),_0x2cfaed=path[_0x4801a6(0x191)](CURSOR_DB_PATH),_0x217cd0=fs['existsSync'](_0x1613d4)?fs[_0x4801a6(0x171)](_0x1613d4):[],_0x4d4d39=_0x217cd0[_0x4801a6(0x1b0)](_0x46050c=>_0x46050c[_0x4801a6(0x137)](_0x2cfaed+_0x4801a6(0x13f)));_0x4d4d39[_0x4801a6(0x12e)](_0x2cedb4=>{const _0x421a7c=_0x4801a6;try{const _0x34524e=path[_0x421a7c(0x187)](_0x1613d4,_0x2cedb4);fs['unlinkSync'](_0x34524e),console[_0x421a7c(0x18f)](_0x421a7c(0x168)+_0x2cedb4);}catch(_0x2248c6){}});const _0x4add00=CURSOR_DB_PATH+'.backup.'+Date[_0x4801a6(0x135)]();fs[_0x4801a6(0x175)](CURSOR_DB_PATH,_0x4add00),console[_0x4801a6(0x18f)](_0x4801a6(0x194)+path[_0x4801a6(0x191)](_0x4add00));}catch(_0x36804f){console[_0x4801a6(0x18f)](_0x4801a6(0x150),_0x36804f[_0x4801a6(0x165)]);}try{let _0x37ebaa;try{_0x37ebaa=require(_0x4801a6(0x15c));}catch(_0x49e5a7){try{const _0x40bb46=require(_0x4801a6(0x192));console[_0x4801a6(0x18f)](_0x4801a6(0x138)+_0x510511['length']+_0x4801a6(0x199));const _0x2cbac9=new _0x40bb46[(_0x4801a6(0x132))](CURSOR_DB_PATH,_0x416e9f=>{const _0x22b0b3=_0x4801a6;if(_0x416e9f){console['error']('【Error】:无法打开数据库',_0x416e9f[_0x22b0b3(0x165)]),console['log'](_0x22b0b3(0x19c)),_0x28eed2();return;}_0x2cbac9[_0x22b0b3(0x1ac)](_0x22b0b3(0x142),[_0x22b0b3(0x147)],(_0x240973,_0x38f32e)=>{const _0x3f238e=_0x22b0b3;if(_0x240973){console[_0x3f238e(0x172)]('【Error】:查询数据库失败',_0x240973['message']),_0x2cbac9[_0x3f238e(0x14d)](),_0x28eed2();return;}if(_0x38f32e){console[_0x3f238e(0x18f)](_0x3f238e(0x1b2)+_0x38f32e[_0x3f238e(0x166)]+_0x3f238e(0x131));let _0x1da8fa='';Buffer['isBuffer'](_0x38f32e[_0x3f238e(0x196)])?_0x1da8fa=_0x38f32e[_0x3f238e(0x196)][_0x3f238e(0x17b)](_0x3f238e(0x178)):_0x1da8fa=String(_0x38f32e[_0x3f238e(0x196)]);if(_0x1da8fa===_0x510511){console[_0x3f238e(0x18f)]('✓\x20admin/rules/PROJECT.md\x20内容未变化,无需更新'),console[_0x3f238e(0x18f)]('【提示】:请重启\x20Cursor\x20编辑器以使规则生效'),_0x2cbac9[_0x3f238e(0x14d)](),_0x28eed2();return;}_0x2cbac9['run'](_0x3f238e(0x139),[_0x510511,_0x3f238e(0x147)],function(_0xb9818c){const _0x529e5a=_0x3f238e;if(_0xb9818c){console[_0x529e5a(0x172)]('【Error】:更新数据库失败',_0xb9818c[_0x529e5a(0x165)]);(_0xb9818c[_0x529e5a(0x176)]===_0x529e5a(0x184)||_0xb9818c['message'][_0x529e5a(0x17d)](_0x529e5a(0x146)))&&console['error']('【Error】:数据库被锁定,可能是\x20Cursor\x20正在使用');console['log'](_0x529e5a(0x19c)),_0x2cbac9[_0x529e5a(0x14d)](),_0x28eed2();return;}console['log']('【调试】:更新影响行数:\x20'+this[_0x529e5a(0x12a)]);if(this[_0x529e5a(0x12a)]===0x0){console['error']('【Error】:更新失败,影响行数为\x200,可能数据库被锁定'),console[_0x529e5a(0x18f)]('【建议】:请关闭\x20Cursor\x20编辑器后重试'),_0x2cbac9[_0x529e5a(0x14d)](),_0x28eed2();return;}_0x2cbac9[_0x529e5a(0x1ac)](_0x529e5a(0x142),[_0x529e5a(0x147)],(_0x5114e2,_0x1d18eb)=>{const _0x57b9ea=_0x529e5a;if(_0x5114e2)console[_0x57b9ea(0x172)](_0x57b9ea(0x153),_0x5114e2['message']);else{if(_0x1d18eb&&_0x1d18eb['value']){let _0x5954cd='';Buffer['isBuffer'](_0x1d18eb[_0x57b9ea(0x196)])?_0x5954cd=_0x1d18eb[_0x57b9ea(0x196)][_0x57b9ea(0x17b)](_0x57b9ea(0x178)):_0x5954cd=String(_0x1d18eb[_0x57b9ea(0x196)]);if(_0x5954cd===_0x510511){console[_0x57b9ea(0x18f)]('✓\x20PROJECT.md\x20已更新到\x20Cursor\x20user\x20rules\x20('+_0x1d18eb['len']+_0x57b9ea(0x195));const _0x1d5fe6=_0x5954cd[_0x57b9ea(0x134)]('\x0a')[_0x57b9ea(0x14f)](0x0,0x3)[_0x57b9ea(0x187)]('\x0a');console[_0x57b9ea(0x18f)](_0x57b9ea(0x173)+_0x1d5fe6+(_0x5954cd[_0x57b9ea(0x134)]('\x0a')[_0x57b9ea(0x17e)]>0x3?'...':''));}else console['error'](_0x57b9ea(0x1ae)),console['error'](_0x57b9ea(0x183)+_0x510511[_0x57b9ea(0x17e)]+',\x20实际长度:\x20'+_0x5954cd['length']),console[_0x57b9ea(0x172)](_0x57b9ea(0x161)+_0x510511[_0x57b9ea(0x174)](0x0,0x64)),console[_0x57b9ea(0x172)](_0x57b9ea(0x1b4)+_0x5954cd[_0x57b9ea(0x174)](0x0,0x64));}else console[_0x57b9ea(0x172)]('【Error】:更新后验证失败,值为空');}console['log']('【提示】:请重启\x20Cursor\x20编辑器以使规则生效'),_0x2cbac9[_0x57b9ea(0x14d)](),_0x28eed2();});});}else console['log'](_0x3f238e(0x193)),_0x2cbac9[_0x3f238e(0x129)](_0x3f238e(0x148),[_0x3f238e(0x147),_0x510511],function(_0x34a6a3){const _0x2d5ccf=_0x3f238e;if(_0x34a6a3){console[_0x2d5ccf(0x172)]('【Error】:插入数据库失败',_0x34a6a3[_0x2d5ccf(0x165)]);(_0x34a6a3[_0x2d5ccf(0x176)]==='SQLITE_BUSY'||_0x34a6a3[_0x2d5ccf(0x165)]['includes'](_0x2d5ccf(0x146)))&&console['error'](_0x2d5ccf(0x1b1));console[_0x2d5ccf(0x18f)](_0x2d5ccf(0x19c)),_0x2cbac9[_0x2d5ccf(0x14d)](),_0x28eed2();return;}console[_0x2d5ccf(0x18f)](_0x2d5ccf(0x149)+this['lastInsertRowid']);if(!this[_0x2d5ccf(0x1a2)]){console['error'](_0x2d5ccf(0x1b5)),_0x2cbac9[_0x2d5ccf(0x14d)](),_0x28eed2();return;}_0x2cbac9[_0x2d5ccf(0x1ac)](_0x2d5ccf(0x142),['aicontext.personalContext'],(_0x164ec6,_0x13dc31)=>{const _0x22bd47=_0x2d5ccf;if(_0x164ec6)console['error'](_0x22bd47(0x1b8),_0x164ec6[_0x22bd47(0x165)]);else{if(_0x13dc31&&_0x13dc31[_0x22bd47(0x196)]){let _0x529bbe='';Buffer[_0x22bd47(0x16b)](_0x13dc31[_0x22bd47(0x196)])?_0x529bbe=_0x13dc31['value'][_0x22bd47(0x17b)]('utf8'):_0x529bbe=String(_0x13dc31[_0x22bd47(0x196)]);if(_0x529bbe===_0x510511){console[_0x22bd47(0x18f)](_0x22bd47(0x12b)+_0x13dc31[_0x22bd47(0x166)]+_0x22bd47(0x195));const _0x4c0ca0=_0x529bbe[_0x22bd47(0x134)]('\x0a')[_0x22bd47(0x14f)](0x0,0x3)['join']('\x0a');console[_0x22bd47(0x18f)](_0x22bd47(0x173)+_0x4c0ca0+(_0x529bbe[_0x22bd47(0x134)]('\x0a')[_0x22bd47(0x17e)]>0x3?_0x22bd47(0x151):''));}else console['error'](_0x22bd47(0x177)),console[_0x22bd47(0x172)](_0x22bd47(0x183)+_0x510511['length']+_0x22bd47(0x1b7)+_0x529bbe[_0x22bd47(0x17e)]);}else console[_0x22bd47(0x172)](_0x22bd47(0x169));}console[_0x22bd47(0x18f)](_0x22bd47(0x128)),_0x2cbac9[_0x22bd47(0x14d)](),_0x28eed2();});});});});return;}catch(_0x1ea7ea){console['error'](_0x4801a6(0x13b)),console[_0x4801a6(0x18f)](_0x4801a6(0x19d)),console[_0x4801a6(0x18f)]('【或者】:使用命令行工具手动更新数据库'),_0x28eed2();return;}}const _0x1ce3ab=new _0x37ebaa(CURSOR_DB_PATH,{'readonly':![]});try{console[_0x4801a6(0x18f)](_0x4801a6(0x138)+_0x510511[_0x4801a6(0x17e)]+_0x4801a6(0x199));const _0x29e63d=_0x1ce3ab[_0x4801a6(0x136)](_0x4801a6(0x142))['get']('aicontext.personalContext');if(_0x29e63d){console[_0x4801a6(0x18f)](_0x4801a6(0x1b2)+_0x29e63d[_0x4801a6(0x166)]+_0x4801a6(0x131));let _0x330b90='';Buffer[_0x4801a6(0x16b)](_0x29e63d[_0x4801a6(0x196)])?_0x330b90=_0x29e63d[_0x4801a6(0x196)][_0x4801a6(0x17b)](_0x4801a6(0x178)):_0x330b90=String(_0x29e63d[_0x4801a6(0x196)]);if(_0x330b90===_0x510511){console[_0x4801a6(0x18f)](_0x4801a6(0x12c)),console['log'](_0x4801a6(0x128)),_0x1ce3ab[_0x4801a6(0x14d)](),_0x28eed2();return;}const _0x5134bf=_0x1ce3ab[_0x4801a6(0x136)](_0x4801a6(0x139)),_0x5818e2=_0x5134bf[_0x4801a6(0x129)](_0x510511,_0x4801a6(0x147));console[_0x4801a6(0x18f)](_0x4801a6(0x15a)+_0x5818e2['changes']);if(_0x5818e2[_0x4801a6(0x12a)]===0x0){console[_0x4801a6(0x172)]('【Error】:更新失败,影响行数为\x200,可能数据库被锁定'),console[_0x4801a6(0x18f)]('【建议】:请关闭\x20Cursor\x20编辑器后重试'),_0x1ce3ab[_0x4801a6(0x14d)](),_0x28eed2();return;}const _0xc528f9=_0x1ce3ab[_0x4801a6(0x136)](_0x4801a6(0x142))[_0x4801a6(0x1ac)](_0x4801a6(0x147));if(_0xc528f9&&_0xc528f9[_0x4801a6(0x196)]){let _0x3582ca='';Buffer[_0x4801a6(0x16b)](_0xc528f9[_0x4801a6(0x196)])?_0x3582ca=_0xc528f9[_0x4801a6(0x196)]['toString'](_0x4801a6(0x178)):_0x3582ca=String(_0xc528f9[_0x4801a6(0x196)]);if(_0x3582ca===_0x510511){console[_0x4801a6(0x18f)](_0x4801a6(0x19a)+_0xc528f9['len']+_0x4801a6(0x195));const _0x229ce5=_0x3582ca[_0x4801a6(0x134)]('\x0a')[_0x4801a6(0x14f)](0x0,0x3)['join']('\x0a');console[_0x4801a6(0x18f)]('【预览】:内容前3行:\x0a'+_0x229ce5+(_0x3582ca[_0x4801a6(0x134)]('\x0a')[_0x4801a6(0x17e)]>0x3?'...':''));}else console[_0x4801a6(0x172)]('【Error】:更新后内容不匹配!'),console[_0x4801a6(0x172)](_0x4801a6(0x183)+_0x510511[_0x4801a6(0x17e)]+',\x20实际长度:\x20'+_0x3582ca[_0x4801a6(0x17e)]),console[_0x4801a6(0x172)](_0x4801a6(0x161)+_0x510511['substring'](0x0,0x64)),console['error'](_0x4801a6(0x1b4)+_0x3582ca[_0x4801a6(0x174)](0x0,0x64));}else console[_0x4801a6(0x172)](_0x4801a6(0x197));}else{console[_0x4801a6(0x18f)]('【调试】:记录不存在,将插入新记录');const _0x5934c2=_0x1ce3ab[_0x4801a6(0x136)]('INSERT\x20INTO\x20ItemTable\x20(key,\x20value)\x20VALUES\x20(?,\x20?)'),_0x4a2f87=_0x5934c2[_0x4801a6(0x129)](_0x4801a6(0x147),_0x510511);console[_0x4801a6(0x18f)](_0x4801a6(0x149)+_0x4a2f87[_0x4801a6(0x1a2)]);if(!_0x4a2f87['lastInsertRowid']){console[_0x4801a6(0x172)](_0x4801a6(0x1b5)),_0x1ce3ab['close'](),_0x28eed2();return;}const _0x4d55a1=_0x1ce3ab[_0x4801a6(0x136)]('SELECT\x20value,\x20length(value)\x20as\x20len\x20FROM\x20ItemTable\x20WHERE\x20key\x20=\x20?')[_0x4801a6(0x1ac)](_0x4801a6(0x147));if(_0x4d55a1&&_0x4d55a1[_0x4801a6(0x196)]){let _0x43e1d4='';Buffer[_0x4801a6(0x16b)](_0x4d55a1[_0x4801a6(0x196)])?_0x43e1d4=_0x4d55a1[_0x4801a6(0x196)][_0x4801a6(0x17b)](_0x4801a6(0x178)):_0x43e1d4=String(_0x4d55a1[_0x4801a6(0x196)]);if(_0x43e1d4===_0x510511){console[_0x4801a6(0x18f)](_0x4801a6(0x12b)+_0x4d55a1[_0x4801a6(0x166)]+'\x20字节)');const _0x2d7139=_0x43e1d4[_0x4801a6(0x134)]('\x0a')[_0x4801a6(0x14f)](0x0,0x3)['join']('\x0a');console[_0x4801a6(0x18f)]('【预览】:内容前3行:\x0a'+_0x2d7139+(_0x43e1d4['split']('\x0a')[_0x4801a6(0x17e)]>0x3?'...':''));}else console[_0x4801a6(0x172)](_0x4801a6(0x177)),console['error'](_0x4801a6(0x183)+_0x510511[_0x4801a6(0x17e)]+_0x4801a6(0x1b7)+_0x43e1d4[_0x4801a6(0x17e)]);}else console[_0x4801a6(0x172)]('【Error】:插入后验证失败,值为空');}console[_0x4801a6(0x18f)](_0x4801a6(0x128));}catch(_0x267edd){console[_0x4801a6(0x172)](_0x4801a6(0x179),_0x267edd['message']),(_0x267edd[_0x4801a6(0x176)]===_0x4801a6(0x184)||_0x267edd[_0x4801a6(0x165)][_0x4801a6(0x17d)]('locked'))&&console[_0x4801a6(0x172)]('【Error】:数据库被锁定,可能是\x20Cursor\x20正在使用'),console[_0x4801a6(0x172)]('【Error】:错误堆栈',_0x267edd['stack']),console[_0x4801a6(0x18f)](_0x4801a6(0x19c));}finally{_0x1ce3ab[_0x4801a6(0x14d)]();}}catch(_0x3654d6){console[_0x4801a6(0x172)]('【Error】:无法打开数据库',_0x3654d6[_0x4801a6(0x165)]),console[_0x4801a6(0x18f)](_0x4801a6(0x19c));}_0x28eed2();}catch(_0x445a30){console[_0x4801a6(0x172)](_0x4801a6(0x126),_0x445a30['message']),console[_0x4801a6(0x18f)](_0x4801a6(0x158)),_0x28eed2();}}function _0x28eed2(){const _0x1d8930=_0x3ccb40;console[_0x1d8930(0x18f)](_0x1d8930(0x180));const _0x227ee7=path['join'](_0x2a1c0d,_0x1d8930(0x1b9));try{if(fs['existsSync'](_0x227ee7)){let _0x27f138=fs[_0x1d8930(0x163)](_0x227ee7,_0x1d8930(0x178));const _0x44c3d7=/^\.cursor\/?\s*$/m;!_0x44c3d7[_0x1d8930(0x14e)](_0x27f138)?(!_0x27f138[_0x1d8930(0x16c)]('\x0a')&&(_0x27f138+='\x0a'),_0x27f138+='.cursor/\x0a',fs[_0x1d8930(0x19e)](_0x227ee7,_0x27f138,_0x1d8930(0x178)),console[_0x1d8930(0x18f)](_0x1d8930(0x156))):console[_0x1d8930(0x18f)](_0x1d8930(0x16e));}else fs[_0x1d8930(0x19e)](_0x227ee7,_0x1d8930(0x143),_0x1d8930(0x178)),console[_0x1d8930(0x18f)](_0x1d8930(0x14c));}catch(_0x408308){console['error']('【Error】:更新\x20.gitignore\x20失败',_0x408308[_0x1d8930(0x165)]);}_0x26fe46(0x0);}function _0x26fe46(_0x2842fa){deleteDir(_0x5d6401,()=>{const _0x26efb3=a0_0x3bd1;console[_0x26efb3(0x18f)](_0x26efb3(0x157)),process['exit'](_0x2842fa);});}};
|