zen-gitsync 2.6.4 → 2.6.5

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.
@@ -6,10 +6,10 @@
6
6
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Zen-GitSync - Git同步工具</title>
9
- <script type="module" crossorigin src="/assets/index-C-nRMJvh.js"></script>
10
- <link rel="modulepreload" crossorigin href="/assets/vendor-DtkI0iJs.js">
9
+ <script type="module" crossorigin src="/assets/index-D0xeSSyV.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/vendor-CiRPTLQ-.js">
11
11
  <link rel="stylesheet" crossorigin href="/assets/vendor-D9qDBEE1.css">
12
- <link rel="stylesheet" crossorigin href="/assets/index-42GyTYVk.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-DmFxzTUu.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="app"></div>
@@ -7,23 +7,15 @@ import open from 'open';
7
7
  import config from '../../config.js';
8
8
  import chalk from 'chalk';
9
9
  import fs from 'fs/promises';
10
+ import fsSync from 'fs';
10
11
  import os from 'os';
11
12
  import { Server } from 'socket.io';
12
- import chokidar from 'chokidar';
13
13
  import { spawn } from 'child_process';
14
14
  // import { exec } from 'child_process';
15
15
 
16
16
  const __filename = fileURLToPath(import.meta.url);
17
17
  const __dirname = path.dirname(__filename);
18
18
  const configManager = config; // 确保 configManager 可用
19
-
20
- // 文件系统变动监控器
21
- let watcher = null;
22
- // 防抖计时器
23
- let debounceTimer = null;
24
- // 防抖延迟时间 (毫秒)
25
- const DEBOUNCE_DELAY = 1000;
26
-
27
19
  // 分支状态缓存
28
20
  let branchStatusCache = {
29
21
  currentBranch: null,
@@ -661,12 +653,6 @@ async function startUIServer(noOpen = false, savePort = false) {
661
653
  console.warn('初始化项目配置失败:', e?.message || e);
662
654
  }
663
655
 
664
- // 关闭旧的文件监控
665
- if (watcher) {
666
- watcher.close().catch(err => console.error('关闭旧监控器失败:', err));
667
- watcher = null;
668
- }
669
-
670
656
  // 通知所有旧房间的客户端项目已切换
671
657
  io.to(projectRoomId).emit('project_changed', {
672
658
  oldProjectPath: currentProjectPath,
@@ -694,11 +680,6 @@ async function startUIServer(noOpen = false, savePort = false) {
694
680
  projectRoomId = newProjectRoomId;
695
681
  isGitRepo = false;
696
682
 
697
- if (watcher) {
698
- watcher.close().catch(err => console.error('关闭监控器失败:', err));
699
- watcher = null;
700
- }
701
-
702
683
  // 通知所有旧房间的客户端项目已切换
703
684
  io.to(projectRoomId).emit('project_changed', {
704
685
  oldProjectPath: currentProjectPath,
@@ -1446,6 +1427,53 @@ async function startUIServer(noOpen = false, savePort = false) {
1446
1427
  }
1447
1428
  })
1448
1429
 
1430
+ // 置顶模板
1431
+ app.post('/api/config/pin-template', express.json(), async (req, res) => {
1432
+ try {
1433
+ const { template, type } = req.body
1434
+
1435
+ if (!template || !type) {
1436
+ return res.status(400).json({ success: false, error: '缺少必要参数' })
1437
+ }
1438
+
1439
+ const config = await configManager.loadConfig()
1440
+
1441
+ if (type === 'description') {
1442
+ if (config.descriptionTemplates) {
1443
+ // 删除原位置的模板
1444
+ config.descriptionTemplates = config.descriptionTemplates.filter(t => t !== template)
1445
+ // 添加到第一位
1446
+ config.descriptionTemplates.unshift(template)
1447
+ await configManager.saveConfig(config)
1448
+ } else {
1449
+ return res.status(404).json({ success: false, error: '模板列表不存在' })
1450
+ }
1451
+ } else if (type === 'scope') {
1452
+ if (config.scopeTemplates) {
1453
+ config.scopeTemplates = config.scopeTemplates.filter(t => t !== template)
1454
+ config.scopeTemplates.unshift(template)
1455
+ await configManager.saveConfig(config)
1456
+ } else {
1457
+ return res.status(404).json({ success: false, error: '模板列表不存在' })
1458
+ }
1459
+ } else if (type === 'message') {
1460
+ if (config.messageTemplates) {
1461
+ config.messageTemplates = config.messageTemplates.filter(t => t !== template)
1462
+ config.messageTemplates.unshift(template)
1463
+ await configManager.saveConfig(config)
1464
+ } else {
1465
+ return res.status(404).json({ success: false, error: '模板列表不存在' })
1466
+ }
1467
+ } else {
1468
+ return res.status(400).json({ success: false, error: '不支持的模板类型' })
1469
+ }
1470
+
1471
+ res.json({ success: true })
1472
+ } catch (error) {
1473
+ res.status(500).json({ success: false, error: error.message })
1474
+ }
1475
+ })
1476
+
1449
1477
  // 保存自定义命令
1450
1478
  app.post('/api/config/save-custom-command', express.json(), async (req, res) => {
1451
1479
  try {
@@ -3369,7 +3397,8 @@ async function startUIServer(noOpen = false, savePort = false) {
3369
3397
  path: dir,
3370
3398
  relativePath: relativePath || '.',
3371
3399
  name: packageData.name || path.basename(dir),
3372
- scripts: packageData.scripts
3400
+ scripts: packageData.scripts,
3401
+ version: packageData.version || '0.0.0'
3373
3402
  });
3374
3403
  return true;
3375
3404
  }
@@ -3555,6 +3584,340 @@ async function startUIServer(noOpen = false, savePort = false) {
3555
3584
  });
3556
3585
  }
3557
3586
  });
3587
+
3588
+ // API: 更新npm版本号
3589
+ app.post('/api/update-npm-version', async (req, res) => {
3590
+ try {
3591
+ const { packagePath, versionType } = req.body;
3592
+
3593
+ if (!packagePath || !versionType) {
3594
+ return res.status(400).json({
3595
+ success: false,
3596
+ error: '缺少必要参数: packagePath, versionType'
3597
+ });
3598
+ }
3599
+
3600
+ // 确保路径指向package.json文件
3601
+ let packageJsonPath = path.resolve(packagePath);
3602
+ if (fsSync.existsSync(packageJsonPath) && fsSync.statSync(packageJsonPath).isDirectory()) {
3603
+ packageJsonPath = path.join(packageJsonPath, 'package.json');
3604
+ }
3605
+
3606
+ // 检查文件是否存在
3607
+ if (!fsSync.existsSync(packageJsonPath)) {
3608
+ return res.status(404).json({
3609
+ success: false,
3610
+ error: '找不到package.json文件'
3611
+ });
3612
+ }
3613
+
3614
+ // 读取package.json
3615
+ const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf8'));
3616
+
3617
+ if (!packageJson.version) {
3618
+ return res.status(400).json({
3619
+ success: false,
3620
+ error: 'package.json中没有version字段'
3621
+ });
3622
+ }
3623
+
3624
+ const oldVersion = packageJson.version;
3625
+ const versionParts = oldVersion.split('.').map(Number);
3626
+
3627
+ // 根据类型增加版本号
3628
+ switch (versionType) {
3629
+ case 'major':
3630
+ versionParts[0]++;
3631
+ versionParts[1] = 0;
3632
+ versionParts[2] = 0;
3633
+ break;
3634
+ case 'minor':
3635
+ versionParts[1]++;
3636
+ versionParts[2] = 0;
3637
+ break;
3638
+ case 'patch':
3639
+ versionParts[2]++;
3640
+ break;
3641
+ default:
3642
+ return res.status(400).json({
3643
+ success: false,
3644
+ error: '无效的版本类型,必须是 major, minor 或 patch'
3645
+ });
3646
+ }
3647
+
3648
+ const newVersion = versionParts.join('.');
3649
+ packageJson.version = newVersion;
3650
+
3651
+ // 写回文件
3652
+ fsSync.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
3653
+
3654
+ console.log(`已更新npm版本号: ${oldVersion} → ${newVersion} (${packagePath})`);
3655
+
3656
+ res.json({
3657
+ success: true,
3658
+ oldVersion,
3659
+ newVersion
3660
+ });
3661
+ } catch (error) {
3662
+ console.error('更新版本号失败:', error);
3663
+ res.status(500).json({
3664
+ success: false,
3665
+ error: `更新版本号失败: ${error.message}`
3666
+ });
3667
+ }
3668
+ });
3669
+
3670
+ // API: 添加npm脚本
3671
+ app.post('/api/add-npm-script', async (req, res) => {
3672
+ try {
3673
+ const { packagePath, scriptName, scriptCommand } = req.body;
3674
+
3675
+ if (!packagePath || !scriptName || !scriptCommand) {
3676
+ return res.status(400).json({
3677
+ success: false,
3678
+ error: '缺少必要参数: packagePath, scriptName, scriptCommand'
3679
+ });
3680
+ }
3681
+
3682
+ // 确保路径指向package.json文件
3683
+ let packageJsonPath = path.resolve(packagePath);
3684
+ if (fsSync.existsSync(packageJsonPath) && fsSync.statSync(packageJsonPath).isDirectory()) {
3685
+ packageJsonPath = path.join(packageJsonPath, 'package.json');
3686
+ }
3687
+
3688
+ // 检查文件是否存在
3689
+ if (!fsSync.existsSync(packageJsonPath)) {
3690
+ return res.status(404).json({
3691
+ success: false,
3692
+ error: '找不到package.json文件'
3693
+ });
3694
+ }
3695
+
3696
+ // 读取package.json
3697
+ const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf8'));
3698
+
3699
+ // 确保scripts对象存在
3700
+ if (!packageJson.scripts) {
3701
+ packageJson.scripts = {};
3702
+ }
3703
+
3704
+ // 检查脚本是否已存在
3705
+ if (packageJson.scripts[scriptName]) {
3706
+ return res.status(400).json({
3707
+ success: false,
3708
+ error: `脚本 "${scriptName}" 已存在`
3709
+ });
3710
+ }
3711
+
3712
+ // 添加脚本
3713
+ packageJson.scripts[scriptName] = scriptCommand;
3714
+
3715
+ // 写回文件(保持格式化)
3716
+ fsSync.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
3717
+
3718
+ console.log(`已添加npm脚本: ${scriptName} = ${scriptCommand} (${packagePath})`);
3719
+
3720
+ res.json({
3721
+ success: true,
3722
+ scriptName,
3723
+ scriptCommand
3724
+ });
3725
+ } catch (error) {
3726
+ console.error('添加npm脚本失败:', error);
3727
+ res.status(500).json({
3728
+ success: false,
3729
+ error: `添加npm脚本失败: ${error.message}`
3730
+ });
3731
+ }
3732
+ });
3733
+
3734
+ // API: 更新npm脚本
3735
+ app.post('/api/update-npm-script', async (req, res) => {
3736
+ try {
3737
+ const { packagePath, scriptName, scriptCommand, oldScriptName } = req.body;
3738
+
3739
+ if (!packagePath || !scriptName || !scriptCommand) {
3740
+ return res.status(400).json({
3741
+ success: false,
3742
+ error: '缺少必要参数: packagePath, scriptName, scriptCommand'
3743
+ });
3744
+ }
3745
+
3746
+ // 确保路径指向package.json文件
3747
+ let packageJsonPath = path.resolve(packagePath);
3748
+ if (fsSync.existsSync(packageJsonPath) && fsSync.statSync(packageJsonPath).isDirectory()) {
3749
+ packageJsonPath = path.join(packageJsonPath, 'package.json');
3750
+ }
3751
+
3752
+ // 检查文件是否存在
3753
+ if (!fsSync.existsSync(packageJsonPath)) {
3754
+ return res.status(404).json({
3755
+ success: false,
3756
+ error: '找不到package.json文件'
3757
+ });
3758
+ }
3759
+
3760
+ // 读取package.json
3761
+ const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf8'));
3762
+
3763
+ // 确保scripts对象存在
3764
+ if (!packageJson.scripts) {
3765
+ packageJson.scripts = {};
3766
+ }
3767
+
3768
+ // 如果改了脚本名称,删除旧的
3769
+ if (oldScriptName && oldScriptName !== scriptName) {
3770
+ delete packageJson.scripts[oldScriptName];
3771
+ }
3772
+
3773
+ // 更新脚本
3774
+ packageJson.scripts[scriptName] = scriptCommand;
3775
+
3776
+ // 写回文件
3777
+ fsSync.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
3778
+
3779
+ console.log(`已更新npm脚本: ${scriptName} = ${scriptCommand} (${packagePath})`);
3780
+
3781
+ res.json({
3782
+ success: true,
3783
+ scriptName,
3784
+ scriptCommand
3785
+ });
3786
+ } catch (error) {
3787
+ console.error('更新npm脚本失败:', error);
3788
+ res.status(500).json({
3789
+ success: false,
3790
+ error: `更新npm脚本失败: ${error.message}`
3791
+ });
3792
+ }
3793
+ });
3794
+
3795
+ // API: 删除npm脚本
3796
+ app.post('/api/delete-npm-script', async (req, res) => {
3797
+ try {
3798
+ const { packagePath, scriptName } = req.body;
3799
+
3800
+ if (!packagePath || !scriptName) {
3801
+ return res.status(400).json({
3802
+ success: false,
3803
+ error: '缺少必要参数: packagePath, scriptName'
3804
+ });
3805
+ }
3806
+
3807
+ // 确保路径指向package.json文件
3808
+ let packageJsonPath = path.resolve(packagePath);
3809
+ if (fsSync.existsSync(packageJsonPath) && fsSync.statSync(packageJsonPath).isDirectory()) {
3810
+ packageJsonPath = path.join(packageJsonPath, 'package.json');
3811
+ }
3812
+
3813
+ // 检查文件是否存在
3814
+ if (!fsSync.existsSync(packageJsonPath)) {
3815
+ return res.status(404).json({
3816
+ success: false,
3817
+ error: '找不到package.json文件'
3818
+ });
3819
+ }
3820
+
3821
+ // 读取package.json
3822
+ const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf8'));
3823
+
3824
+ // 检查scripts对象和脚本是否存在
3825
+ if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
3826
+ return res.status(404).json({
3827
+ success: false,
3828
+ error: `脚本 "${scriptName}" 不存在`
3829
+ });
3830
+ }
3831
+
3832
+ // 删除脚本
3833
+ delete packageJson.scripts[scriptName];
3834
+
3835
+ // 写回文件
3836
+ fsSync.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
3837
+
3838
+ console.log(`已删除npm脚本: ${scriptName} (${packagePath})`);
3839
+
3840
+ res.json({
3841
+ success: true,
3842
+ scriptName
3843
+ });
3844
+ } catch (error) {
3845
+ console.error('删除npm脚本失败:', error);
3846
+ res.status(500).json({
3847
+ success: false,
3848
+ error: `删除npm脚本失败: ${error.message}`
3849
+ });
3850
+ }
3851
+ });
3852
+
3853
+ // API: 置顶npm脚本
3854
+ app.post('/api/pin-npm-script', async (req, res) => {
3855
+ try {
3856
+ const { packagePath, scriptName } = req.body;
3857
+
3858
+ if (!packagePath || !scriptName) {
3859
+ return res.status(400).json({
3860
+ success: false,
3861
+ error: '缺少必要参数: packagePath, scriptName'
3862
+ });
3863
+ }
3864
+
3865
+ // 确保路径指向package.json文件
3866
+ let packageJsonPath = path.resolve(packagePath);
3867
+ if (fsSync.existsSync(packageJsonPath) && fsSync.statSync(packageJsonPath).isDirectory()) {
3868
+ packageJsonPath = path.join(packageJsonPath, 'package.json');
3869
+ }
3870
+
3871
+ // 检查文件是否存在
3872
+ if (!fsSync.existsSync(packageJsonPath)) {
3873
+ return res.status(404).json({
3874
+ success: false,
3875
+ error: '找不到package.json文件'
3876
+ });
3877
+ }
3878
+
3879
+ // 读取package.json
3880
+ const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf8'));
3881
+
3882
+ // 检查scripts对象和脚本是否存在
3883
+ if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
3884
+ return res.status(404).json({
3885
+ success: false,
3886
+ error: `脚本 "${scriptName}" 不存在`
3887
+ });
3888
+ }
3889
+
3890
+ // 保存要置顶的脚本内容
3891
+ const scriptCommand = packageJson.scripts[scriptName];
3892
+
3893
+ // 删除该脚本
3894
+ delete packageJson.scripts[scriptName];
3895
+
3896
+ // 创建新的scripts对象,将置顶脚本放在最前面
3897
+ const newScripts = {
3898
+ [scriptName]: scriptCommand,
3899
+ ...packageJson.scripts
3900
+ };
3901
+
3902
+ packageJson.scripts = newScripts;
3903
+
3904
+ // 写回文件
3905
+ fsSync.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
3906
+
3907
+ console.log(`已置顶npm脚本: ${scriptName} (${packagePath})`);
3908
+
3909
+ res.json({
3910
+ success: true,
3911
+ scriptName
3912
+ });
3913
+ } catch (error) {
3914
+ console.error('置顶npm脚本失败:', error);
3915
+ res.status(500).json({
3916
+ success: false,
3917
+ error: `置顶npm脚本失败: ${error.message}`
3918
+ });
3919
+ }
3920
+ });
3558
3921
 
3559
3922
  // Socket.io 实时更新
3560
3923
  io.on('connection', (socket) => {
@@ -3571,34 +3934,6 @@ async function startUIServer(noOpen = false, savePort = false) {
3571
3934
  const history = getCommandHistory();
3572
3935
  socket.emit('initial_command_history', { history });
3573
3936
 
3574
- // 发送项目信息给客户端
3575
- socket.emit('project_info', {
3576
- projectPath: currentProjectPath,
3577
- projectRoomId: projectRoomId
3578
- });
3579
-
3580
- // 客户端可以请求开始/停止监控
3581
- socket.on('start_monitoring', () => {
3582
- if (!watcher) {
3583
- initFileSystemWatcher().catch(err => console.error('[文件监控] 初始化失败:', err));
3584
- socket.emit('monitoring_status', { active: true });
3585
- }
3586
- });
3587
-
3588
- // 处理客户端加入新房间的请求
3589
- socket.on('join_room', (roomId) => {
3590
- socket.join(roomId);
3591
- console.log(`客户端 ${socket.id} 已加入房间: ${roomId}`);
3592
- });
3593
-
3594
- socket.on('stop_monitoring', () => {
3595
- if (watcher) {
3596
- watcher.close().catch(err => console.error('关闭监控器失败:', err));
3597
- watcher = null;
3598
- socket.emit('monitoring_status', { active: false });
3599
- }
3600
- });
3601
-
3602
3937
  // 请求完整命令历史
3603
3938
  socket.on('request_full_history', () => {
3604
3939
  const fullHistory = getCommandHistory();
@@ -3618,158 +3953,6 @@ async function startUIServer(noOpen = false, savePort = false) {
3618
3953
  });
3619
3954
  });
3620
3955
 
3621
- // 读取并解析.gitignore文件
3622
- async function parseGitignore(projectPath) {
3623
- const gitignorePath = path.join(projectPath, '.gitignore');
3624
- const ignorePatterns = [
3625
- /(^|[\/\\])\../, // 始终忽略.开头的文件(除了.gitignore本身)
3626
- '**/.git/**', // 始终忽略.git目录
3627
-
3628
- // 额外排除常见的编译产物和大文件,减少监控开销
3629
- '**/*.umd.cjs', // UMD打包文件
3630
- '**/*.min.js', // 压缩JS文件
3631
- '**/*.bundle.js', // Webpack打包文件
3632
- '**/*.dist.js', // 构建产物
3633
- '**/*.prod.js', // 生产环境文件
3634
- '**/lib/**', // 通常是编译产物
3635
- '**/es/**', // ES模块编译产物
3636
- '**/esm/**', // ES模块编译产物
3637
- '**/*.map', // Source map文件
3638
- '**/*.chunk.js', // 代码分割chunk
3639
- ];
3640
-
3641
- try {
3642
- const gitignoreContent = await fs.readFile(gitignorePath, 'utf8');
3643
- const lines = gitignoreContent.split('\n');
3644
- let validRules = 0;
3645
-
3646
- for (let line of lines) {
3647
- line = line.trim();
3648
-
3649
- // 跳过空行和注释
3650
- if (!line || line.startsWith('#')) continue;
3651
-
3652
- // 移除行尾的空格
3653
- line = line.replace(/\s+$/, '');
3654
-
3655
- // 跳过否定规则(chokidar不支持否定规则,这些规则会被忽略)
3656
- if (line.startsWith('!')) {
3657
- continue;
3658
- }
3659
-
3660
- // 将gitignore规则转换为glob模式
3661
- let pattern;
3662
-
3663
- // 如果以/开头,表示从根目录开始匹配
3664
- if (line.startsWith('/')) {
3665
- pattern = line.substring(1);
3666
- // 如果是目录,添加/**后缀
3667
- if (!pattern.includes('*') && !pattern.includes('.')) {
3668
- ignorePatterns.push(pattern);
3669
- ignorePatterns.push(pattern + '/**');
3670
- } else {
3671
- ignorePatterns.push(pattern);
3672
- }
3673
- } else if (line.endsWith('/')) {
3674
- // 明确的目录规则
3675
- const dirName = line.slice(0, -1);
3676
- ignorePatterns.push('**/' + dirName);
3677
- ignorePatterns.push('**/' + dirName + '/**');
3678
- } else {
3679
- // 文件或目录规则
3680
- // 如果包含*通配符,直接使用
3681
- if (line.includes('*')) {
3682
- ignorePatterns.push('**/' + line);
3683
- } else {
3684
- // 既匹配文件也匹配目录
3685
- ignorePatterns.push('**/' + line);
3686
- ignorePatterns.push('**/' + line + '/**');
3687
- }
3688
- }
3689
-
3690
- validRules++;
3691
- }
3692
-
3693
- console.log(`[文件监控] 从.gitignore读取了 ${validRules} 条有效的忽略规则`);
3694
- } catch (error) {
3695
- // .gitignore不存在或读取失败,使用默认规则
3696
- console.log('[文件监控] 未找到.gitignore,使用默认忽略规则');
3697
- ignorePatterns.push(
3698
- '**/node_modules/**',
3699
- '**/dist/**',
3700
- '**/build/**',
3701
- '**/coverage/**',
3702
- '**/.nuxt/**',
3703
- '**/.next/**',
3704
- '**/out/**',
3705
- '**/*.log'
3706
- );
3707
- }
3708
-
3709
- return ignorePatterns;
3710
- }
3711
-
3712
- // 初始化文件系统监控
3713
- async function initFileSystemWatcher() {
3714
- // 停止已有的监控器
3715
- if (watcher) {
3716
- watcher.close().catch(err => console.error('关闭旧监控器失败:', err));
3717
- }
3718
-
3719
- try {
3720
- // 获取当前工作目录
3721
- const currentDir = process.cwd();
3722
-
3723
- console.log(`初始化文件系统监控器,路径: ${currentDir}`);
3724
-
3725
- // 检查是否是Git仓库
3726
- if (!isGitRepo) {
3727
- console.log('当前目录不是Git仓库,不启动监控');
3728
- return;
3729
- }
3730
-
3731
- const watcherStartTime = Date.now();
3732
- console.log('[文件监控] 开始初始化监控器...');
3733
-
3734
- // 从.gitignore读取忽略规则
3735
- const ignorePatterns = await parseGitignore(currentDir);
3736
-
3737
- // 使用chokidar监控文件变动
3738
- watcher = chokidar.watch(currentDir, {
3739
- ignored: ignorePatterns,
3740
- persistent: true,
3741
- ignoreInitial: true, // 忽略初始扫描时的文件
3742
- depth: 10, // 限制扫描深度,避免过深的目录结构
3743
- awaitWriteFinish: {
3744
- stabilityThreshold: 300, // 等待文件写入完成的时间
3745
- pollInterval: 100 // 轮询间隔
3746
- }
3747
- });
3748
-
3749
- // 合并所有变动事件到一个处理程序
3750
- const events = ['add', 'change', 'unlink'];
3751
- events.forEach(event => {
3752
- watcher.on(event, path => {
3753
- console.log(`检测到文件变动 [${event}]: ${path}`);
3754
- debouncedNotifyChanges();
3755
- });
3756
- });
3757
-
3758
- watcher.on('ready', () => {
3759
- const initTime = Date.now() - watcherStartTime;
3760
- console.log(`[文件监控] 监控器初始化完成,耗时 ${initTime}ms`);
3761
- });
3762
-
3763
- watcher.on('error', error => {
3764
- console.error('[文件监控] 监控错误:', error);
3765
- });
3766
-
3767
- console.log('[文件监控] 监控器已启动(异步初始化中...)');
3768
- } catch (error) {
3769
- console.error('启动文件监控失败:', error);
3770
- }
3771
- }
3772
-
3773
3956
  // 获取并广播Git状态 (优化版本 - 只获取porcelain格式)
3774
3957
  async function getAndBroadcastStatus() {
3775
3958
  try {
@@ -3801,17 +3984,6 @@ async function startUIServer(noOpen = false, savePort = false) {
3801
3984
  }
3802
3985
  }
3803
3986
 
3804
- // 防抖处理函数
3805
- function debouncedNotifyChanges() {
3806
- if (debounceTimer) {
3807
- clearTimeout(debounceTimer);
3808
- }
3809
-
3810
- debounceTimer = setTimeout(() => {
3811
- getAndBroadcastStatus();
3812
- }, DEBOUNCE_DELAY);
3813
- }
3814
-
3815
3987
  // 检查当前目录是否是Git仓库
3816
3988
  let isGitRepo = false;
3817
3989
  try {