zen-gitsync 2.5.1 → 2.6.1

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.
@@ -1,16 +1,17 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Zen-GitSync - Git同步工具</title>
8
- <script type="module" crossorigin src="/assets/index-CnCbYqLq.js"></script>
9
- <link rel="modulepreload" crossorigin href="/assets/vendor-Dys2BbyU.js">
10
- <link rel="stylesheet" crossorigin href="/assets/vendor-HJmoQ7iQ.css">
11
- <link rel="stylesheet" crossorigin href="/assets/index-BApDCqKk.css">
12
- </head>
13
- <body>
14
- <div id="app"></div>
15
- </body>
16
- </html>
1
+ <!doctype html>
2
+ <html lang="zh-CN" translate="no">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="google" content="notranslate" />
6
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>Zen-GitSync - Git同步工具</title>
9
+ <script type="module" crossorigin src="/assets/index-BlZI1-J0.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/vendor-TIhvVDcs.js">
11
+ <link rel="stylesheet" crossorigin href="/assets/vendor-D9qDBEE1.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-D0V6ggoJ.css">
13
+ </head>
14
+ <body>
15
+ <div id="app"></div>
16
+ </body>
17
+ </html>
@@ -96,8 +96,41 @@ async function startUIServer(noOpen = false, savePort = false) {
96
96
 
97
97
  // 添加请求日志中间件
98
98
  app.use((req, res, next) => {
99
- const now = new Date().toLocaleString();
100
- console.log(`[${now}] ${req.method} ${req.url}`);
99
+ const startTime = Date.now();
100
+ const requestTime = new Date().toLocaleString('zh-CN', { hour12: false });
101
+
102
+ // 监听响应完成事件
103
+ res.on('finish', () => {
104
+ const duration = Date.now() - startTime;
105
+ const statusCode = res.statusCode;
106
+
107
+ // 根据状态码选择颜色
108
+ let statusColor = chalk.green;
109
+ if (statusCode >= 400 && statusCode < 500) {
110
+ statusColor = chalk.yellow;
111
+ } else if (statusCode >= 500) {
112
+ statusColor = chalk.red;
113
+ }
114
+
115
+ // 根据请求耗时选择颜色
116
+ let durationColor = chalk.gray;
117
+ if (duration > 1000) {
118
+ durationColor = chalk.red;
119
+ } else if (duration > 500) {
120
+ durationColor = chalk.yellow;
121
+ } else if (duration > 200) {
122
+ durationColor = chalk.cyan;
123
+ }
124
+
125
+ console.log(
126
+ chalk.dim(`[${requestTime}]`),
127
+ chalk.bold(req.method),
128
+ req.url,
129
+ statusColor(`[${statusCode}]`),
130
+ durationColor(`${duration}ms`)
131
+ );
132
+ });
133
+
101
134
  next();
102
135
  });
103
136
 
@@ -592,8 +625,11 @@ async function startUIServer(noOpen = false, savePort = false) {
592
625
  newProjectRoomId: newProjectRoomId
593
626
  });
594
627
 
595
- // 重新初始化文件监控(新路径)
596
- initFileSystemWatcher();
628
+ // 不再自动启动文件监控,只在用户手动开启自动更新开关时启动
629
+ // console.log('[切换目录] 将在3秒后初始化文件监控器');
630
+ // setTimeout(() => {
631
+ // initFileSystemWatcher().catch(err => console.error('[文件监控] 初始化失败:', err));
632
+ // }, 3000);
597
633
 
598
634
  res.json({
599
635
  success: true,
@@ -1940,9 +1976,28 @@ async function startUIServer(noOpen = false, savePort = false) {
1940
1976
  return res.status(400).json({ error: '缺少文件路径参数' });
1941
1977
  }
1942
1978
 
1979
+ // 检查是否是编译/压缩文件(通常很大且不需要查看diff)
1980
+ const isCompiledFile = /\.(min\.js|umd\.cjs|bundle\.js|dist\.js|prod\.js)$/i.test(filePath);
1981
+ if (isCompiledFile) {
1982
+ return res.json({
1983
+ diff: '⚠️ 检测到编译/打包文件,diff内容过大已跳过显示。\n\n提示:这类文件通常是自动生成的,不建议查看diff。\n如需查看,请使用命令行:git diff -- "' + filePath + '"',
1984
+ isLargeFile: true
1985
+ });
1986
+ }
1987
+
1943
1988
  // 执行git diff命令获取文件差异
1944
1989
  const { stdout } = await execGitCommand(`git diff -- "${filePath}"`);
1945
1990
 
1991
+ // 检查diff大小,如果超过500KB,只返回提示
1992
+ const diffSizeKB = Buffer.byteLength(stdout, 'utf8') / 1024;
1993
+ if (diffSizeKB > 500) {
1994
+ return res.json({
1995
+ diff: `⚠️ Diff内容过大 (${diffSizeKB.toFixed(1)}KB),已跳过显示以避免浏览器卡顿。\n\n提示:请使用命令行查看:git diff -- "${filePath}"`,
1996
+ isLargeFile: true,
1997
+ size: diffSizeKB
1998
+ });
1999
+ }
2000
+
1946
2001
  res.json({ diff: stdout });
1947
2002
  } catch (error) {
1948
2003
  res.status(500).json({ error: error.message });
@@ -1957,9 +2012,28 @@ async function startUIServer(noOpen = false, savePort = false) {
1957
2012
  return res.status(400).json({ error: '缺少文件路径参数' });
1958
2013
  }
1959
2014
 
2015
+ // 检查是否是编译/压缩文件
2016
+ const isCompiledFile = /\.(min\.js|umd\.cjs|bundle\.js|dist\.js|prod\.js)$/i.test(filePath);
2017
+ if (isCompiledFile) {
2018
+ return res.json({
2019
+ diff: '⚠️ 检测到编译/打包文件,diff内容过大已跳过显示。\n\n提示:这类文件通常是自动生成的,不建议查看diff。\n如需查看,请使用命令行:git diff --cached -- "' + filePath + '"',
2020
+ isLargeFile: true
2021
+ });
2022
+ }
2023
+
1960
2024
  // 执行git diff --cached命令获取已暂存文件差异
1961
2025
  const { stdout } = await execGitCommand(`git diff --cached -- "${filePath}"`);
1962
2026
 
2027
+ // 检查diff大小
2028
+ const diffSizeKB = Buffer.byteLength(stdout, 'utf8') / 1024;
2029
+ if (diffSizeKB > 500) {
2030
+ return res.json({
2031
+ diff: `⚠️ Diff内容过大 (${diffSizeKB.toFixed(1)}KB),已跳过显示以避免浏览器卡顿。\n\n提示:请使用命令行查看:git diff --cached -- "${filePath}"`,
2032
+ isLargeFile: true,
2033
+ size: diffSizeKB
2034
+ });
2035
+ }
2036
+
1963
2037
  res.json({ diff: stdout });
1964
2038
  } catch (error) {
1965
2039
  res.status(500).json({ error: error.message });
@@ -2891,64 +2965,211 @@ async function startUIServer(noOpen = false, savePort = false) {
2891
2965
 
2892
2966
  // ========== NPM 脚本管理相关 API ==========
2893
2967
 
2968
+ // 存储正在进行的扫描任务
2969
+ let currentScanAbortController = null;
2970
+
2894
2971
  // 扫描项目目录及子目录下的所有package.json,并提取scripts
2895
2972
  app.get('/api/scan-npm-scripts', async (req, res) => {
2973
+ // 取消之前的扫描
2974
+ if (currentScanAbortController) {
2975
+ currentScanAbortController.aborted = true;
2976
+ }
2977
+
2978
+ // 创建新的abort controller
2979
+ currentScanAbortController = {
2980
+ aborted: false,
2981
+ abort() { this.aborted = true; }
2982
+ };
2983
+ const scanController = currentScanAbortController;
2896
2984
  try {
2897
2985
  const projectRoot = process.cwd();
2898
2986
  const packageJsons = [];
2987
+ const startTime = Date.now();
2988
+
2989
+ console.log(`[NPM扫描-后端] 开始扫描项目: ${projectRoot}`);
2990
+
2991
+ // 需要忽略的目录列表(更全面)
2992
+ const IGNORED_DIRS = new Set([
2993
+ 'node_modules',
2994
+ '.git',
2995
+ '.svn',
2996
+ '.hg',
2997
+ 'dist',
2998
+ 'build',
2999
+ 'coverage',
3000
+ 'out',
3001
+ 'target',
3002
+ 'vendor',
3003
+ '__pycache__',
3004
+ '.next',
3005
+ '.nuxt',
3006
+ '.vscode',
3007
+ '.idea',
3008
+ 'tmp',
3009
+ 'temp',
3010
+ 'cache',
3011
+ '.cache'
3012
+ ]);
3013
+
3014
+ // 优先扫描的子目录(monorepo常见结构)
3015
+ const PRIORITY_DIRS = ['packages', 'apps', 'libs', 'services', 'modules'];
3016
+
3017
+ let scannedCount = 0;
3018
+ let skippedCount = 0;
3019
+ let fileReadCount = 0; // 统计实际读取的文件数量
3020
+
3021
+ // 检查指定目录下是否有package.json
3022
+ async function checkPackageJson(dir) {
3023
+ if (scanController.aborted) return false;
3024
+
3025
+ try {
3026
+ const packagePath = path.join(dir, 'package.json');
3027
+
3028
+ // 先检查文件是否存在,避免不必要的读取
3029
+ try {
3030
+ await fs.access(packagePath);
3031
+ } catch {
3032
+ // 文件不存在,直接返回
3033
+ return false;
3034
+ }
3035
+
3036
+ // 检查文件大小,避免读取异常大的文件
3037
+ const stats = await fs.stat(packagePath);
3038
+ const fileSizeMB = stats.size / (1024 * 1024);
3039
+ if (fileSizeMB > 1) {
3040
+ // package.json超过1MB是异常情况,跳过
3041
+ console.log(`[NPM扫描] 跳过超大文件 (${fileSizeMB.toFixed(2)}MB): ${packagePath}`);
3042
+ return false;
3043
+ }
3044
+
3045
+ fileReadCount++; // 只有文件存在且大小合理时才计数
3046
+ const content = await fs.readFile(packagePath, 'utf8');
3047
+ const packageData = JSON.parse(content);
3048
+
3049
+ // 只有当scripts存在且至少有一个脚本时才添加
3050
+ if (packageData.scripts && Object.keys(packageData.scripts).length > 0) {
3051
+ const relativePath = path.relative(projectRoot, dir);
3052
+ packageJsons.push({
3053
+ path: dir,
3054
+ relativePath: relativePath || '.',
3055
+ name: packageData.name || path.basename(dir),
3056
+ scripts: packageData.scripts
3057
+ });
3058
+ return true;
3059
+ }
3060
+ } catch (error) {
3061
+ // 文件不存在或解析失败,忽略
3062
+ }
3063
+ return false;
3064
+ }
3065
+
3066
+ // 递归扫描目录,最大深度4层
3067
+ const MAX_DEPTH = 4;
3068
+ const MAX_DIRS_PER_LEVEL = 50; // 每层最多扫描50个子目录
3069
+
3070
+ // 统计每层深度的扫描数量
3071
+ const depthStats = Array(MAX_DEPTH + 1).fill(0).map(() => ({ count: 0, time: 0 }));
2899
3072
 
2900
- // 递归扫描目录查找package.json
2901
3073
  async function scanDirectory(dir, depth = 0) {
2902
- // 限制扫描深度,避免扫描过深
2903
- if (depth > 5) return;
3074
+ if (scanController.aborted) return;
3075
+ if (depth > MAX_DEPTH) return;
3076
+
3077
+ const depthStart = Date.now();
3078
+ scannedCount++;
3079
+ depthStats[depth].count++;
2904
3080
 
3081
+ // 检查当前目录的package.json
3082
+ await checkPackageJson(dir);
3083
+
3084
+ // 如果已经达到最大深度,不再继续
3085
+ if (depth >= MAX_DEPTH) return;
3086
+
3087
+ // 读取子目录
2905
3088
  try {
3089
+ if (scanController.aborted) return;
3090
+
2906
3091
  const items = await fs.readdir(dir, { withFileTypes: true });
3092
+ const subDirs = [];
2907
3093
 
3094
+ // 收集所有子目录
2908
3095
  for (const item of items) {
2909
- const fullPath = path.join(dir, item.name);
3096
+ if (scanController.aborted) return;
3097
+ if (!item.isDirectory()) continue;
2910
3098
 
2911
- // 跳过常见的不需要扫描的目录
2912
- if (item.isDirectory()) {
2913
- const dirName = item.name;
2914
- if (dirName === 'node_modules' ||
2915
- dirName === '.git' ||
2916
- dirName === 'dist' ||
2917
- dirName === 'build' ||
2918
- dirName.startsWith('.')) {
2919
- continue;
2920
- }
2921
-
2922
- // 递归扫描子目录
2923
- await scanDirectory(fullPath, depth + 1);
2924
- } else if (item.name === 'package.json') {
2925
- // 读取package.json文件
2926
- try {
2927
- const content = await fs.readFile(fullPath, 'utf8');
2928
- const packageData = JSON.parse(content);
2929
-
2930
- // 只有当scripts存在且至少有一个脚本时才添加
2931
- if (packageData.scripts && Object.keys(packageData.scripts).length > 0) {
2932
- const relativePath = path.relative(projectRoot, dir);
2933
- packageJsons.push({
2934
- path: dir,
2935
- relativePath: relativePath || '.',
2936
- name: packageData.name || path.basename(dir),
2937
- scripts: packageData.scripts
2938
- });
2939
- }
2940
- } catch (error) {
2941
- console.error(`读取package.json失败: ${fullPath}`, error);
2942
- }
3099
+ const dirName = item.name;
3100
+
3101
+ // 跳过忽略的目录
3102
+ if (IGNORED_DIRS.has(dirName) || dirName.startsWith('.')) {
3103
+ skippedCount++;
3104
+ continue;
2943
3105
  }
3106
+
3107
+ subDirs.push(item);
3108
+ }
3109
+
3110
+ // 限制每层扫描的子目录数量
3111
+ const dirsToScan = subDirs.slice(0, MAX_DIRS_PER_LEVEL);
3112
+ if (subDirs.length > MAX_DIRS_PER_LEVEL) {
3113
+ skippedCount += subDirs.length - MAX_DIRS_PER_LEVEL;
3114
+ }
3115
+
3116
+ // 优先处理优先目录
3117
+ const priorityDirs = dirsToScan.filter(item => PRIORITY_DIRS.includes(item.name));
3118
+ const normalDirs = dirsToScan.filter(item => !PRIORITY_DIRS.includes(item.name));
3119
+
3120
+ // 先扫描优先目录
3121
+ for (const item of priorityDirs) {
3122
+ if (scanController.aborted) return;
3123
+ const subDirPath = path.join(dir, item.name);
3124
+ await scanDirectory(subDirPath, depth + 1);
3125
+ }
3126
+
3127
+ // 再扫描普通目录
3128
+ for (const item of normalDirs) {
3129
+ if (scanController.aborted) return;
3130
+ const subDirPath = path.join(dir, item.name);
3131
+ await scanDirectory(subDirPath, depth + 1);
2944
3132
  }
3133
+
2945
3134
  } catch (error) {
2946
- console.error(`扫描目录失败: ${dir}`, error);
3135
+ // 忽略无法访问的目录
2947
3136
  }
3137
+
3138
+ // 记录该深度的耗时
3139
+ depthStats[depth].time += Date.now() - depthStart;
2948
3140
  }
2949
3141
 
2950
- // 从项目根目录开始扫描
2951
- await scanDirectory(projectRoot);
3142
+ // 执行递归扫描
3143
+ console.log(`[NPM扫描-后端] 开始递归扫描(最大深度${MAX_DEPTH}层)`);
3144
+ const scanStart = Date.now();
3145
+ await scanDirectory(projectRoot, 0);
3146
+ console.log(`[NPM扫描-后端] 递归扫描完成,耗时${Date.now() - scanStart}ms`);
3147
+
3148
+ // 扫描完成,清除abort controller
3149
+ if (currentScanAbortController === scanController) {
3150
+ currentScanAbortController = null;
3151
+ }
3152
+
3153
+ const scanTime = Date.now() - startTime;
3154
+
3155
+ if (scanController.aborted) {
3156
+ console.log(`npm脚本扫描被取消,耗时${scanTime}ms`);
3157
+ return res.json({
3158
+ success: true,
3159
+ packages: [],
3160
+ totalScripts: 0,
3161
+ cancelled: true
3162
+ });
3163
+ }
3164
+
3165
+ // 输出每层深度的统计
3166
+ const depthInfo = depthStats
3167
+ .map((stat, depth) => stat.count > 0 ? `深度${depth}:${stat.count}个(${stat.time}ms)` : null)
3168
+ .filter(Boolean)
3169
+ .join(', ');
3170
+
3171
+ console.log(`npm脚本扫描完成,耗时${scanTime}ms,扫描了${scannedCount}个目录,读取了${fileReadCount}个package.json文件,跳过${skippedCount}个目录,找到${packageJsons.length}个有效的package.json`);
3172
+ console.log(`[NPM扫描-后端] 深度分布: ${depthInfo}`);
2952
3173
 
2953
3174
  res.json({
2954
3175
  success: true,
@@ -3043,7 +3264,7 @@ async function startUIServer(noOpen = false, savePort = false) {
3043
3264
  // 客户端可以请求开始/停止监控
3044
3265
  socket.on('start_monitoring', () => {
3045
3266
  if (!watcher) {
3046
- initFileSystemWatcher();
3267
+ initFileSystemWatcher().catch(err => console.error('[文件监控] 初始化失败:', err));
3047
3268
  socket.emit('monitoring_status', { active: true });
3048
3269
  }
3049
3270
  });
@@ -3081,8 +3302,99 @@ async function startUIServer(noOpen = false, savePort = false) {
3081
3302
  });
3082
3303
  });
3083
3304
 
3305
+ // 读取并解析.gitignore文件
3306
+ async function parseGitignore(projectPath) {
3307
+ const gitignorePath = path.join(projectPath, '.gitignore');
3308
+ const ignorePatterns = [
3309
+ /(^|[\/\\])\../, // 始终忽略.开头的文件(除了.gitignore本身)
3310
+ '**/.git/**', // 始终忽略.git目录
3311
+
3312
+ // 额外排除常见的编译产物和大文件,减少监控开销
3313
+ '**/*.umd.cjs', // UMD打包文件
3314
+ '**/*.min.js', // 压缩JS文件
3315
+ '**/*.bundle.js', // Webpack打包文件
3316
+ '**/*.dist.js', // 构建产物
3317
+ '**/*.prod.js', // 生产环境文件
3318
+ '**/lib/**', // 通常是编译产物
3319
+ '**/es/**', // ES模块编译产物
3320
+ '**/esm/**', // ES模块编译产物
3321
+ '**/*.map', // Source map文件
3322
+ '**/*.chunk.js', // 代码分割chunk
3323
+ ];
3324
+
3325
+ try {
3326
+ const gitignoreContent = await fs.readFile(gitignorePath, 'utf8');
3327
+ const lines = gitignoreContent.split('\n');
3328
+ let validRules = 0;
3329
+
3330
+ for (let line of lines) {
3331
+ line = line.trim();
3332
+
3333
+ // 跳过空行和注释
3334
+ if (!line || line.startsWith('#')) continue;
3335
+
3336
+ // 移除行尾的空格
3337
+ line = line.replace(/\s+$/, '');
3338
+
3339
+ // 跳过否定规则(chokidar不支持否定规则,这些规则会被忽略)
3340
+ if (line.startsWith('!')) {
3341
+ continue;
3342
+ }
3343
+
3344
+ // 将gitignore规则转换为glob模式
3345
+ let pattern;
3346
+
3347
+ // 如果以/开头,表示从根目录开始匹配
3348
+ if (line.startsWith('/')) {
3349
+ pattern = line.substring(1);
3350
+ // 如果是目录,添加/**后缀
3351
+ if (!pattern.includes('*') && !pattern.includes('.')) {
3352
+ ignorePatterns.push(pattern);
3353
+ ignorePatterns.push(pattern + '/**');
3354
+ } else {
3355
+ ignorePatterns.push(pattern);
3356
+ }
3357
+ } else if (line.endsWith('/')) {
3358
+ // 明确的目录规则
3359
+ const dirName = line.slice(0, -1);
3360
+ ignorePatterns.push('**/' + dirName);
3361
+ ignorePatterns.push('**/' + dirName + '/**');
3362
+ } else {
3363
+ // 文件或目录规则
3364
+ // 如果包含*通配符,直接使用
3365
+ if (line.includes('*')) {
3366
+ ignorePatterns.push('**/' + line);
3367
+ } else {
3368
+ // 既匹配文件也匹配目录
3369
+ ignorePatterns.push('**/' + line);
3370
+ ignorePatterns.push('**/' + line + '/**');
3371
+ }
3372
+ }
3373
+
3374
+ validRules++;
3375
+ }
3376
+
3377
+ console.log(`[文件监控] 从.gitignore读取了 ${validRules} 条有效的忽略规则`);
3378
+ } catch (error) {
3379
+ // .gitignore不存在或读取失败,使用默认规则
3380
+ console.log('[文件监控] 未找到.gitignore,使用默认忽略规则');
3381
+ ignorePatterns.push(
3382
+ '**/node_modules/**',
3383
+ '**/dist/**',
3384
+ '**/build/**',
3385
+ '**/coverage/**',
3386
+ '**/.nuxt/**',
3387
+ '**/.next/**',
3388
+ '**/out/**',
3389
+ '**/*.log'
3390
+ );
3391
+ }
3392
+
3393
+ return ignorePatterns;
3394
+ }
3395
+
3084
3396
  // 初始化文件系统监控
3085
- function initFileSystemWatcher() {
3397
+ async function initFileSystemWatcher() {
3086
3398
  // 停止已有的监控器
3087
3399
  if (watcher) {
3088
3400
  watcher.close().catch(err => console.error('关闭旧监控器失败:', err));
@@ -3100,15 +3412,18 @@ async function startUIServer(noOpen = false, savePort = false) {
3100
3412
  return;
3101
3413
  }
3102
3414
 
3415
+ const watcherStartTime = Date.now();
3416
+ console.log('[文件监控] 开始初始化监控器...');
3417
+
3418
+ // 从.gitignore读取忽略规则
3419
+ const ignorePatterns = await parseGitignore(currentDir);
3420
+
3103
3421
  // 使用chokidar监控文件变动
3104
3422
  watcher = chokidar.watch(currentDir, {
3105
- ignored: [
3106
- /(^|[\/\\])\../, // 忽略.开头的文件和目录
3107
- '**/node_modules/**', // 忽略node_modules
3108
- '**/.git/**', // 忽略.git目录
3109
- ],
3423
+ ignored: ignorePatterns,
3110
3424
  persistent: true,
3111
3425
  ignoreInitial: true, // 忽略初始扫描时的文件
3426
+ depth: 10, // 限制扫描深度,避免过深的目录结构
3112
3427
  awaitWriteFinish: {
3113
3428
  stabilityThreshold: 300, // 等待文件写入完成的时间
3114
3429
  pollInterval: 100 // 轮询间隔
@@ -3124,11 +3439,16 @@ async function startUIServer(noOpen = false, savePort = false) {
3124
3439
  });
3125
3440
  });
3126
3441
 
3442
+ watcher.on('ready', () => {
3443
+ const initTime = Date.now() - watcherStartTime;
3444
+ console.log(`[文件监控] 监控器初始化完成,耗时 ${initTime}ms`);
3445
+ });
3446
+
3127
3447
  watcher.on('error', error => {
3128
- console.error('文件监控错误:', error);
3448
+ console.error('[文件监控] 监控错误:', error);
3129
3449
  });
3130
3450
 
3131
- console.log('文件系统监控器已启动');
3451
+ console.log('[文件监控] 监控器已启动(异步初始化中...)');
3132
3452
  } catch (error) {
3133
3453
  console.error('启动文件监控失败:', error);
3134
3454
  }
@@ -3275,9 +3595,10 @@ async function startUIServer(noOpen = false, savePort = false) {
3275
3595
  console.log(chalk.green(` 启动时间: ${new Date().toLocaleString()}`));
3276
3596
 
3277
3597
  if (isGitRepo) {
3278
- console.log(chalk.green(` 当前目录是Git仓库,文件监控已启动`));
3279
- // 启动文件监控
3280
- initFileSystemWatcher();
3598
+ console.log(chalk.green(` 当前目录是Git仓库`));
3599
+ console.log(chalk.yellow(` 文件监控已禁用(默认),需要时请在前端开启自动更新开关`));
3600
+ // 不再自动启动文件监控,只在用户开启自动更新开关时启动
3601
+ // initFileSystemWatcher().catch(err => console.error('[文件监控] 初始化失败:', err));
3281
3602
  } else {
3282
3603
  console.log(chalk.yellow(` 当前目录不是Git仓库,文件监控未启动`));
3283
3604
  }
@@ -202,6 +202,11 @@ function execSyncGitCommand(command, options = {}) {
202
202
  }
203
203
  let result = output.trim()
204
204
  log && coloredLog(head, result)
205
+ // 打印当前目录和时间信息
206
+ if (log) {
207
+ const currentTime = new Date().toLocaleString('zh-CN', { hour12: false });
208
+ console.log(chalk.dim(`📁 目录: ${cwd} | ⏰ 时间: ${currentTime}`));
209
+ }
205
210
  return result
206
211
  } catch (e) {
207
212
  // console.log(`执行命令出错 ==> `, command, e)
@@ -312,8 +317,18 @@ function execGitCommand(command, options = {}) {
312
317
  if (stderr) {
313
318
  log && coloredLog(head, stderr)
314
319
  }
320
+ // 打印当前目录和时间信息
321
+ if (log && (stdout || stderr)) {
322
+ const currentTime = new Date().toLocaleString('zh-CN', { hour12: false });
323
+ console.log(chalk.dim(`📁 目录: ${cwd} | ⏰ 时间: ${currentTime}`));
324
+ }
315
325
  if (error) {
316
326
  log && coloredLog(head, error, 'error')
327
+ // 错误情况也打印目录和时间
328
+ if (log) {
329
+ const currentTime = new Date().toLocaleString('zh-CN', { hour12: false });
330
+ console.log(chalk.dim(`📁 目录: ${cwd} | ⏰ 时间: ${currentTime}`));
331
+ }
317
332
  reject(error)
318
333
  return
319
334
  }