ccman 0.0.4 → 1.0.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.
@@ -0,0 +1,322 @@
1
+ #!/bin/bash
2
+
3
+ # CCM Enhanced Release Script
4
+ # 增强版快速发布脚本 - 支持智能代码处理和发布状态监控
5
+
6
+ set -e
7
+
8
+ # 颜色定义
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ RED='\033[0;31m'
12
+ BLUE='\033[0;34m'
13
+ CYAN='\033[0;36m'
14
+ NC='\033[0m'
15
+
16
+ print_success() { echo -e "${GREEN}✅ $1${NC}"; }
17
+ print_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
18
+ print_error() { echo -e "${RED}❌ $1${NC}"; exit 1; }
19
+ print_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
20
+ print_check() { echo -e "${CYAN}🔍 $1${NC}"; }
21
+
22
+ # 检查基本环境
23
+ check_environment() {
24
+ [ ! -f "package.json" ] && print_error "package.json 未找到"
25
+ [ ! -d ".git" ] && print_error "不在 Git 仓库中"
26
+
27
+ if ! command -v curl &> /dev/null; then
28
+ print_warning "curl 未安装,将跳过发布状态检查"
29
+ SKIP_STATUS_CHECK=true
30
+ fi
31
+ }
32
+
33
+ # 智能处理未提交代码
34
+ handle_uncommitted_changes() {
35
+ print_info "检查工作目录状态..."
36
+
37
+ if git diff-index --quiet HEAD --; then
38
+ print_success "工作目录干净"
39
+ return 0
40
+ fi
41
+
42
+ print_warning "发现未提交的更改:"
43
+ git status --short
44
+ echo ""
45
+
46
+ echo "请选择处理方式:"
47
+ echo "1) 提交所有更改并继续发布"
48
+ echo "2) 暂存所有更改并继续发布"
49
+ echo "3) 取消发布,手动处理"
50
+ echo ""
51
+
52
+ read -p "请选择 (1-3): " choice
53
+
54
+ case $choice in
55
+ 1)
56
+ read -p "输入提交信息: " commit_msg
57
+ [ -z "$commit_msg" ] && commit_msg="chore: 发布前提交未完成更改"
58
+
59
+ git add .
60
+ git commit -m "$commit_msg"
61
+ print_success "所有更改已提交"
62
+ ;;
63
+ 2)
64
+ git add .
65
+ print_success "所有更改已暂存"
66
+ ;;
67
+ 3)
68
+ print_info "发布已取消,请手动处理更改后重新运行"
69
+ exit 0
70
+ ;;
71
+ *)
72
+ print_error "无效选择"
73
+ ;;
74
+ esac
75
+ }
76
+
77
+ # 获取和选择版本
78
+ get_and_select_version() {
79
+ current_version=$(node -p "require('./package.json').version")
80
+ version_type=${1:-""}
81
+
82
+ echo "🚀 CCM 智能发布"
83
+ echo "当前版本: $current_version"
84
+ echo ""
85
+
86
+ if [ -z "$version_type" ]; then
87
+ print_info "选择版本升级类型:"
88
+ echo "1) patch (修订版本): $current_version → $(pnpm version patch --dry-run 2>/dev/null | cut -d'v' -f2 || echo '计算中...')"
89
+ echo "2) minor (次版本): $current_version → $(pnpm version minor --dry-run 2>/dev/null | cut -d'v' -f2 || echo '计算中...')"
90
+ echo "3) major (主版本): $current_version → $(pnpm version major --dry-run 2>/dev/null | cut -d'v' -f2 || echo '计算中...')"
91
+ echo "4) 跳过版本升级,仅重新发布当前版本"
92
+ echo ""
93
+
94
+ read -p "请选择 (1-4, 回车默认选择 patch): " choice
95
+
96
+ case ${choice:-1} in
97
+ 1|"") version_type="patch" ;;
98
+ 2) version_type="minor" ;;
99
+ 3) version_type="major" ;;
100
+ 4) version_type="skip" ;;
101
+ *) print_error "无效选择" ;;
102
+ esac
103
+ fi
104
+
105
+ print_info "选择: $version_type"
106
+
107
+ if [ "$version_type" != "skip" ]; then
108
+ echo ""
109
+ read -p "确认升级版本? (y/N): " -n 1 -r
110
+ echo
111
+ [[ ! $REPLY =~ ^[Yy]$ ]] && { print_warning "取消发布"; exit 0; }
112
+ fi
113
+ }
114
+
115
+ # 执行发布流程
116
+ execute_release() {
117
+ print_success "开始发布流程..."
118
+
119
+ # 1. 构建和测试
120
+ print_info "运行构建和代码检查..."
121
+ pnpm run build
122
+ pnpm run lint
123
+
124
+ # 2. 更新版本号
125
+ if [ "$version_type" != "skip" ]; then
126
+ print_info "更新版本号..."
127
+ new_version=$(pnpm version $version_type --no-git-tag-version)
128
+ new_version=${new_version#v}
129
+ print_success "版本已更新: $current_version → $new_version"
130
+ else
131
+ new_version=$current_version
132
+ print_info "跳过版本更新,使用当前版本: $new_version"
133
+ fi
134
+
135
+ # 3. 先创建tag,再提交(按你的需求顺序)
136
+ tag_name="v$new_version"
137
+
138
+ if [ "$version_type" != "skip" ]; then
139
+ print_info "创建标签: $tag_name"
140
+ git tag -a "$tag_name" -m "Release v$new_version
141
+
142
+ 🚀 智能发布 $version_type 版本
143
+ ⏰ $(date '+%Y-%m-%d %H:%M:%S')
144
+
145
+ 🤖 Generated with [Claude Code](https://claude.ai/code)
146
+
147
+ Co-Authored-By: Claude <noreply@anthropic.com>"
148
+
149
+ print_info "提交版本更改..."
150
+ git add .
151
+ git commit -m "chore: 发布版本 v$new_version
152
+
153
+ 🚀 智能发布 $version_type 版本,标签 $tag_name 已创建
154
+ ⏰ $(date '+%Y-%m-%d %H:%M:%S')
155
+
156
+ 🤖 Generated with [Claude Code](https://claude.ai/code)
157
+
158
+ Co-Authored-By: Claude <noreply@anthropic.com>"
159
+
160
+ print_success "标签 $tag_name 已创建,更改已提交"
161
+ fi
162
+
163
+ # 4. 推送
164
+ print_info "推送到远程仓库..."
165
+ git push origin $(git branch --show-current)
166
+ git push origin "$tag_name"
167
+
168
+ print_success "版本 v$new_version 已推送,GitHub Actions 已触发"
169
+
170
+ # 输出监控链接(按你的需求)
171
+ print_info "📊 监控链接:"
172
+ echo " 🔗 GitHub Actions: https://github.com/2ue/ccm/actions"
173
+ echo " 🔗 NPM Registry: https://www.npmjs.com/package/ccman"
174
+ echo " 🔗 GitHub Releases: https://github.com/2ue/ccm/releases"
175
+ }
176
+
177
+ # 监控发布状态
178
+ monitor_release_status() {
179
+ if [ "$SKIP_STATUS_CHECK" = true ]; then
180
+ print_warning "跳过发布状态检查"
181
+ show_manual_links
182
+ return 0
183
+ fi
184
+
185
+ print_info "开始监控发布状态..."
186
+ echo ""
187
+
188
+ # GitHub Actions 状态检查
189
+ print_check "检查 GitHub Actions 状态..."
190
+
191
+ local max_attempts=30 # 最多检查5分钟
192
+ local attempt=0
193
+ local actions_success=false
194
+
195
+ while [ $attempt -lt $max_attempts ]; do
196
+ # 检查最新的 workflow run
197
+ local run_status=$(curl -s -H "Accept: application/vnd.github.v3+json" \
198
+ "https://api.github.com/repos/2ue/ccm/actions/runs?per_page=1" \
199
+ | grep -o '"status":"[^"]*"' | head -1 | cut -d'"' -f4 2>/dev/null || echo "unknown")
200
+
201
+ local run_conclusion=$(curl -s -H "Accept: application/vnd.github.v3+json" \
202
+ "https://api.github.com/repos/2ue/ccm/actions/runs?per_page=1" \
203
+ | grep -o '"conclusion":"[^"]*"' | head -1 | cut -d'"' -f4 2>/dev/null || echo "null")
204
+
205
+ case "$run_status" in
206
+ "completed")
207
+ if [ "$run_conclusion" = "success" ]; then
208
+ print_success "GitHub Actions 构建成功!"
209
+ actions_success=true
210
+ break
211
+ else
212
+ print_error "GitHub Actions 构建失败: $run_conclusion"
213
+ return 1
214
+ fi
215
+ ;;
216
+ "in_progress"|"queued")
217
+ echo -ne "\r${CYAN}🔍 GitHub Actions 运行中... (${attempt}/${max_attempts})${NC}"
218
+ ;;
219
+ *)
220
+ echo -ne "\r${YELLOW}⚠️ 等待 GitHub Actions 开始... (${attempt}/${max_attempts})${NC}"
221
+ ;;
222
+ esac
223
+
224
+ sleep 10
225
+ ((attempt++))
226
+ done
227
+
228
+ echo # 换行
229
+
230
+ if [ "$actions_success" != true ]; then
231
+ print_warning "GitHub Actions 检查超时,请手动确认"
232
+ show_manual_links
233
+ return 0
234
+ fi
235
+
236
+ # NPM 发布状态检查
237
+ print_check "检查 NPM 包发布状态..."
238
+
239
+ local npm_attempts=20
240
+ local npm_attempt=0
241
+ local npm_success=false
242
+
243
+ while [ $npm_attempt -lt $npm_attempts ]; do
244
+ local npm_response=$(curl -s "https://registry.npmjs.org/ccman" | grep -o "\"$new_version\"" 2>/dev/null || echo "")
245
+
246
+ if [ -n "$npm_response" ]; then
247
+ print_success "NPM 包 v$new_version 发布成功!"
248
+ npm_success=true
249
+ break
250
+ else
251
+ echo -ne "\r${CYAN}🔍 等待 NPM 包发布... (${npm_attempt}/${npm_attempts})${NC}"
252
+ sleep 15
253
+ ((npm_attempt++))
254
+ fi
255
+ done
256
+
257
+ echo # 换行
258
+
259
+ if [ "$npm_success" != true ]; then
260
+ print_warning "NPM 包检查超时,可能仍在发布中"
261
+ fi
262
+
263
+ # GitHub Release 检查
264
+ print_check "检查 GitHub Release..."
265
+
266
+ local release_response=$(curl -s "https://api.github.com/repos/2ue/ccm/releases/tags/v$new_version" \
267
+ | grep -o '"tag_name":"[^"]*"' 2>/dev/null || echo "")
268
+
269
+ if [ -n "$release_response" ]; then
270
+ print_success "GitHub Release v$new_version 创建成功!"
271
+ else
272
+ print_warning "GitHub Release 可能仍在创建中"
273
+ fi
274
+ }
275
+
276
+ # 显示手动检查链接
277
+ show_manual_links() {
278
+ print_info "请手动检查以下链接:"
279
+ echo " GitHub Actions: https://github.com/2ue/ccm/actions"
280
+ echo " GitHub Release: https://github.com/2ue/ccm/releases/tag/v$new_version"
281
+ echo " NPM 包: https://www.npmjs.com/package/ccman"
282
+ }
283
+
284
+ # 显示发布总结
285
+ show_release_summary() {
286
+ echo ""
287
+ print_success "🎉 发布流程完成!"
288
+ echo ""
289
+ print_info "📋 发布总结:"
290
+ echo " 版本: v$new_version"
291
+ echo " NPM 包: ccman@$new_version"
292
+ echo ""
293
+ print_info "📦 安装命令:"
294
+ echo " npm install -g ccman@$new_version"
295
+ echo ""
296
+ print_info "🔗 相关链接:"
297
+ echo " NPM: https://www.npmjs.com/package/ccman/v/$new_version"
298
+ echo " GitHub: https://github.com/2ue/ccm/releases/tag/v$new_version"
299
+ echo ""
300
+ }
301
+
302
+ # 主函数
303
+ main() {
304
+ print_info "🚀 CCM 智能发布脚本 v2.0"
305
+ print_info "=================================="
306
+ echo ""
307
+
308
+ check_environment
309
+ handle_uncommitted_changes
310
+ get_and_select_version "$1"
311
+ execute_release
312
+ monitor_release_status
313
+ show_release_summary
314
+
315
+ print_success "✨ 发布成功完成!"
316
+ }
317
+
318
+ # 错误处理
319
+ trap 'print_error "发布过程中出现错误,请检查输出信息"' ERR
320
+
321
+ # 运行主函数
322
+ main "$@"
@@ -1,4 +1,4 @@
1
- import * as fs from 'fs';
1
+ import * as fse from 'fs-extra';
2
2
  import * as path from 'path';
3
3
  import * as os from 'os';
4
4
  import { ShellEnvVars, ShellWriteResult, ShellType } from '../types';
@@ -20,38 +20,136 @@ export class ShellManager {
20
20
  */
21
21
  async writeToShell(envVars: ShellEnvVars, envName?: string): Promise<ShellWriteResult> {
22
22
  try {
23
- // 1. 写入环境变量到独立的 ccmanrc 文件
23
+ // 1. 写入环境变量到独立的 ccmanrc 文件(通常不会有权限问题)
24
24
  await this.writeCCMANRC(envVars, envName);
25
25
 
26
- // 2. 确保 shell 配置文件中有对 ccmanrc 的引用
27
- const shellUpdateResult = await this.ensureShellReference();
26
+ // 2. 检查shell配置文件权限
27
+ const shellPermissionCheck = this.checkShellWritePermissions();
28
28
 
29
- return {
30
- success: true,
31
- filePath: this.ccmanrcPath,
32
- message: `Environment variables written to ${this.ccmanrcPath}${shellUpdateResult.updated ? ` and shell reference ${shellUpdateResult.action}` : ''}`
33
- };
29
+ // 3. 尝试更新 shell 配置文件引用
30
+ if (shellPermissionCheck.hasWritableShellConfig) {
31
+ try {
32
+ const shellUpdateResult = await this.ensureShellReference();
33
+ return {
34
+ success: true,
35
+ filePath: this.ccmanrcPath,
36
+ message: `环境变量已写入 ${this.ccmanrcPath}${shellUpdateResult.updated ? ` 并${shellUpdateResult.action}shell引用` : ''}`
37
+ };
38
+ } catch (error) {
39
+ // Shell引用失败但有可写配置文件时,提供具体的手动指导
40
+ return this.createManualConfigResult(shellPermissionCheck, String(error));
41
+ }
42
+ } else {
43
+ // 没有可写的shell配置文件,提供完整的手动配置指导
44
+ return this.createManualConfigResult(shellPermissionCheck);
45
+ }
34
46
  } catch (error) {
35
47
  return {
36
48
  success: false,
37
49
  filePath: this.ccmanrcPath,
38
- message: 'Failed to write environment variables',
50
+ message: '写入环境变量失败',
39
51
  error: String(error)
40
52
  };
41
53
  }
42
54
  }
43
55
 
56
+ /**
57
+ * 创建手动配置结果
58
+ */
59
+ private createManualConfigResult(
60
+ shellPermissionCheck: { shellConfigAccess: { file: string; writable: boolean; error?: string }[] },
61
+ shellError?: string
62
+ ): ShellWriteResult {
63
+ const reference = this.generateShellReference().trim();
64
+ const writableFiles = shellPermissionCheck.shellConfigAccess.filter(f => f.writable);
65
+ const nonWritableFiles = shellPermissionCheck.shellConfigAccess.filter(f => !f.writable);
66
+
67
+ let message = `环境变量已写入 ${this.ccmanrcPath},但需要手动配置shell引用。\n\n`;
68
+
69
+ if (writableFiles.length > 0) {
70
+ message += `推荐添加到以下文件之一:\n`;
71
+ writableFiles.forEach(f => {
72
+ message += ` ✅ ${f.file}\n`;
73
+ });
74
+ }
75
+
76
+ if (nonWritableFiles.length > 0) {
77
+ message += `以下文件无写入权限:\n`;
78
+ nonWritableFiles.forEach(f => {
79
+ message += ` ❌ ${f.file} (${f.error})\n`;
80
+ });
81
+ message += `\n可尝试修复权限:\n`;
82
+ nonWritableFiles.forEach(f => {
83
+ if (f.error === '无写入权限') {
84
+ message += ` chmod 644 ${f.file}\n`;
85
+ }
86
+ });
87
+ }
88
+
89
+ message += `\n需要手动添加的内容:\n${reference}`;
90
+
91
+ return {
92
+ success: true, // ccmanrc写入成功,只是需要手动配置
93
+ filePath: this.ccmanrcPath,
94
+ message,
95
+ error: shellError ? `Shell配置自动更新失败: ${shellError}` : '所有shell配置文件都无写入权限'
96
+ };
97
+ }
98
+
99
+ /**
100
+ * 检查shell配置文件写入权限
101
+ */
102
+ private checkShellWritePermissions(): {
103
+ hasWritableShellConfig: boolean;
104
+ shellConfigAccess: { file: string; writable: boolean; error?: string }[];
105
+ } {
106
+ const result = {
107
+ hasWritableShellConfig: false,
108
+ shellConfigAccess: [] as { file: string; writable: boolean; error?: string }[]
109
+ };
110
+
111
+ const shellType = this.detectShell();
112
+ const configFiles = this.getShellConfigFiles(shellType);
113
+
114
+ for (const configFile of configFiles) {
115
+ const fileCheck = { file: configFile, writable: false, error: undefined as string | undefined };
116
+
117
+ try {
118
+ if (fse.pathExistsSync(configFile)) {
119
+ // 文件存在,检查写入权限
120
+ fse.accessSync(configFile, fse.constants.W_OK);
121
+ fileCheck.writable = true;
122
+ result.hasWritableShellConfig = true;
123
+ } else {
124
+ // 文件不存在,检查父目录权限(能否创建文件)
125
+ const dir = path.dirname(configFile);
126
+ if (fse.pathExistsSync(dir)) {
127
+ fse.accessSync(dir, fse.constants.W_OK);
128
+ fileCheck.writable = true;
129
+ result.hasWritableShellConfig = true;
130
+ } else {
131
+ fileCheck.error = '目录不存在';
132
+ }
133
+ }
134
+ } catch (error: any) {
135
+ fileCheck.error = `无写入权限`;
136
+ }
137
+
138
+ result.shellConfigAccess.push(fileCheck);
139
+ }
140
+
141
+ return result;
142
+ }
143
+
44
144
  /**
45
145
  * 写入 ccmanrc 文件
46
146
  */
47
147
  private async writeCCMANRC(envVars: ShellEnvVars, envName?: string): Promise<void> {
48
148
  // 确保 .ccman 目录存在
49
- if (!fs.existsSync(this.ccmanDir)) {
50
- fs.mkdirSync(this.ccmanDir, { recursive: true });
51
- }
149
+ fse.ensureDirSync(this.ccmanDir);
52
150
 
53
151
  const content = this.generateExportStatements(envVars, envName);
54
- fs.writeFileSync(this.ccmanrcPath, content);
152
+ await fse.writeFile(this.ccmanrcPath, content, 'utf8');
55
153
  }
56
154
 
57
155
  /**
@@ -63,8 +161,8 @@ export class ShellManager {
63
161
 
64
162
  // 检查是否已经有引用
65
163
  for (const configFile of configFiles) {
66
- if (fs.existsSync(configFile)) {
67
- const content = fs.readFileSync(configFile, 'utf8');
164
+ if (fse.pathExistsSync(configFile)) {
165
+ const content = fse.readFileSync(configFile, 'utf8');
68
166
  if (this.hasShellReference(content)) {
69
167
  return { updated: false, action: 'already exists' };
70
168
  }
@@ -104,20 +202,32 @@ export class ShellManager {
104
202
  private async addShellReference(configFilePath: string): Promise<void> {
105
203
  // 确保目录存在
106
204
  const dir = path.dirname(configFilePath);
107
- if (!fs.existsSync(dir)) {
108
- fs.mkdirSync(dir, { recursive: true });
109
- }
205
+ fse.ensureDirSync(dir);
110
206
 
111
207
  let content = '';
112
- if (fs.existsSync(configFilePath)) {
113
- content = fs.readFileSync(configFilePath, 'utf8');
208
+ if (fse.pathExistsSync(configFilePath)) {
209
+ try {
210
+ content = fse.readFileSync(configFilePath, 'utf8');
211
+ } catch (error: any) {
212
+ if (error.code === 'EACCES' || error.code === 'EPERM') {
213
+ throw new Error(`无权限读取shell配置文件 ${configFilePath}`);
214
+ }
215
+ throw error;
216
+ }
114
217
  }
115
218
 
116
219
  // 添加对 ccmanrc 的引用
117
220
  const reference = this.generateShellReference();
118
221
  content += reference;
119
222
 
120
- fs.writeFileSync(configFilePath, content);
223
+ try {
224
+ await fse.writeFile(configFilePath, content, 'utf8');
225
+ } catch (error: any) {
226
+ if (error.code === 'EACCES' || error.code === 'EPERM') {
227
+ throw new Error(`无权限修改shell配置文件 ${configFilePath}。\n建议:\n 1. 检查文件权限:chmod 644 ${configFilePath}\n 2. 或手动添加以下内容到该文件:\n${reference.trim()}`);
228
+ }
229
+ throw error;
230
+ }
121
231
  }
122
232
 
123
233
  /**
@@ -148,9 +258,9 @@ export class ShellManager {
148
258
  let lastError: string | undefined;
149
259
 
150
260
  // 1. 删除 ccmanrc 文件
151
- if (fs.existsSync(this.ccmanrcPath)) {
261
+ if (fse.pathExistsSync(this.ccmanrcPath)) {
152
262
  try {
153
- fs.unlinkSync(this.ccmanrcPath);
263
+ fse.removeSync(this.ccmanrcPath);
154
264
  clearedAny = true;
155
265
  } catch (error) {
156
266
  lastError = String(error);
@@ -163,7 +273,7 @@ export class ShellManager {
163
273
 
164
274
  for (const configFile of configFiles) {
165
275
  try {
166
- if (fs.existsSync(configFile)) {
276
+ if (fse.pathExistsSync(configFile)) {
167
277
  await this.removeShellReference(configFile);
168
278
  clearedAny = true;
169
279
  }
@@ -192,14 +302,14 @@ export class ShellManager {
192
302
  * 从配置文件中移除 shell 引用
193
303
  */
194
304
  private async removeShellReference(filePath: string): Promise<void> {
195
- if (!fs.existsSync(filePath)) {
305
+ if (!fse.pathExistsSync(filePath)) {
196
306
  return;
197
307
  }
198
308
 
199
- const content = fs.readFileSync(filePath, 'utf8');
309
+ const content = fse.readFileSync(filePath, 'utf8');
200
310
  const cleanedContent = this.removeShellReferenceFromContent(content);
201
311
 
202
- fs.writeFileSync(filePath, cleanedContent);
312
+ await fse.writeFile(filePath, cleanedContent, 'utf8');
203
313
  }
204
314
 
205
315
  /**
@@ -313,7 +423,7 @@ export ${CONFIG.ENV_VARS.AUTH_TOKEN}="${envVars.ANTHROPIC_AUTH_TOKEN}"
313
423
  */
314
424
  hasEnvVarsInShell(): boolean {
315
425
  // 检查 ccmanrc 文件是否存在
316
- if (fs.existsSync(this.ccmanrcPath)) {
426
+ if (fse.pathExistsSync(this.ccmanrcPath)) {
317
427
  return true;
318
428
  }
319
429
 
@@ -322,8 +432,8 @@ export ${CONFIG.ENV_VARS.AUTH_TOKEN}="${envVars.ANTHROPIC_AUTH_TOKEN}"
322
432
  const configFiles = this.getShellConfigFiles(shellType);
323
433
 
324
434
  for (const configFile of configFiles) {
325
- if (fs.existsSync(configFile)) {
326
- const content = fs.readFileSync(configFile, 'utf8');
435
+ if (fse.pathExistsSync(configFile)) {
436
+ const content = fse.readFileSync(configFile, 'utf8');
327
437
  if (this.hasShellReference(content)) {
328
438
  return true;
329
439
  }
@@ -341,7 +451,7 @@ export ${CONFIG.ENV_VARS.AUTH_TOKEN}="${envVars.ANTHROPIC_AUTH_TOKEN}"
341
451
  const configFiles = this.getShellConfigFiles(shellType);
342
452
 
343
453
  // 找到第一个存在的配置文件
344
- const activeConfigFile = configFiles.find(file => fs.existsSync(file));
454
+ const activeConfigFile = configFiles.find(file => fse.pathExistsSync(file));
345
455
 
346
456
  if (!activeConfigFile) {
347
457
  return {
@@ -404,7 +514,7 @@ export ${CONFIG.ENV_VARS.AUTH_TOKEN}="${envVars.ANTHROPIC_AUTH_TOKEN}"
404
514
  const configFiles = this.getShellConfigFiles(shellType);
405
515
 
406
516
  // 找到第一个存在的配置文件作为活动配置文件
407
- const activeConfigFile = configFiles.find(file => fs.existsSync(file));
517
+ const activeConfigFile = configFiles.find(file => fse.pathExistsSync(file));
408
518
 
409
519
  return {
410
520
  shellType,