fnva 0.0.14 → 0.0.16

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/README.md CHANGED
@@ -30,13 +30,24 @@ yarn global add fnva
30
30
  pnpm add -g fnva
31
31
 
32
32
  function fnva {
33
- if ($args.Count -ge 2 -and ($args[0] -eq "java" -or $args[0] -eq "llm" -or $args[0] -eq "cc") -and $args[1] -eq "use") {
33
+ if ($args.Count -ge 2 -and ($args[0] -eq "java" -or $args[0] -eq "llm" -or $args[0] -eq "cc") -and ($args[1] -eq "use")) {
34
34
  $tempFile = "$env:TEMP\fnva_script_$(Get-Random).ps1"
35
- & node bin\fnva.js $args | Out-File -FilePath $tempFile -Encoding UTF8
36
- & $tempFile
37
- Remove-Item $tempFile -ErrorAction SilentlyContinue
35
+
36
+ $env:FNVAAUTOMODE = "1"
37
+ try {
38
+ cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args" | Out-File -FilePath $tempFile -Encoding UTF8
39
+ & $tempFile
40
+ } finally {
41
+ $env:FNVAAUTOMODE = ""
42
+ Remove-Item $tempFile -ErrorAction SilentlyContinue
43
+ }
38
44
  } else {
39
- & node bin\fnva.js $args
45
+ $env:FNVAAUTOMODE = "1"
46
+ try {
47
+ cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args"
48
+ } finally {
49
+ $env:FNVAAUTOMODE = ""
50
+ }
40
51
  }
41
52
  }
42
53
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fnva",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "跨平台环境切换工具,支持 Java 和 LLM 环境配置",
5
5
  "author": "protagonistss",
6
6
  "license": "MIT",
@@ -9,12 +9,16 @@
9
9
  },
10
10
  "scripts": {
11
11
  "prepublishOnly": "scripts/prepare-publish.sh",
12
+ "postinstall": "echo 'Setting up fnva shell integration...' && node scripts/install-shell-integration.js --auto",
13
+ "install-shell": "node scripts/install-shell-integration.js",
14
+ "uninstall-shell": "node scripts/uninstall-shell-integration.js",
12
15
  "build": "scripts/build-local.sh",
13
16
  "build:all": "scripts/build-all.sh"
14
17
  },
15
18
  "files": [
16
19
  "bin/",
17
20
  "platforms/",
21
+ "scripts/",
18
22
  "README.md",
19
23
  "LICENSE"
20
24
  ],
package/platforms/fnva CHANGED
Binary file
Binary file
@@ -0,0 +1,94 @@
1
+ #!/bin/bash
2
+
3
+ # 构建所有平台的二进制文件
4
+
5
+ set -e
6
+
7
+ echo "开始构建所有平台的二进制文件..."
8
+
9
+ # 获取项目根目录
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
12
+ PLATFORMS_DIR="$PROJECT_ROOT/platforms"
13
+
14
+ # 创建 platforms 目录
15
+ mkdir -p "$PLATFORMS_DIR"
16
+
17
+ # 检查是否安装了 cross(用于交叉编译)
18
+ if ! command -v cross &> /dev/null; then
19
+ echo "警告: 未找到 cross 工具,尝试安装..."
20
+ cargo install cross --git https://github.com/cross-rs/cross
21
+ fi
22
+
23
+ # 定义目标平台
24
+ TARGETS=(
25
+ "x86_64-apple-darwin|darwin-x64"
26
+ "aarch64-apple-darwin|darwin-arm64"
27
+ "x86_64-unknown-linux-gnu|linux-x64"
28
+ "aarch64-unknown-linux-gnu|linux-arm64"
29
+ "x86_64-pc-windows-msvc|win32-x64"
30
+ )
31
+
32
+ # 构建函数
33
+ build_target() {
34
+ local target=$1
35
+ local platform_name=$2
36
+
37
+ echo ""
38
+ echo "=========================================="
39
+ echo "构建目标: $target"
40
+ echo "平台名称: $platform_name"
41
+ echo "=========================================="
42
+
43
+ # 使用 cross 交叉编译,Windows 使用原生 cargo
44
+ if [[ "$target" == *"windows"* ]]; then
45
+ cargo build --release --target "$target"
46
+ elif command -v cross &> /dev/null; then
47
+ cross build --release --target "$target"
48
+ else
49
+ # 如果没有 cross,尝试直接使用 cargo(仅适用于当前平台)
50
+ cargo build --release --target "$target"
51
+ fi
52
+
53
+ # 确定输出目录和文件名
54
+ local output_dir="$PLATFORMS_DIR/$platform_name"
55
+ mkdir -p "$output_dir"
56
+
57
+ # 确定二进制文件名
58
+ if [[ "$target" == *"windows"* ]]; then
59
+ local binary_name="fnva.exe"
60
+ else
61
+ local binary_name="fnva"
62
+ fi
63
+
64
+ # 复制二进制文件
65
+ local source_binary="$PROJECT_ROOT/target/$target/release/$binary_name"
66
+
67
+ if [ -f "$source_binary" ]; then
68
+ cp "$source_binary" "$output_dir/$binary_name"
69
+ echo "✓ 成功构建: $output_dir/$binary_name"
70
+
71
+ # 可选:压缩二进制文件(使用 strip)
72
+ if command -v strip &> /dev/null && [[ "$binary_name" != "*.exe" ]]; then
73
+ strip "$output_dir/$binary_name"
74
+ echo "✓ 已优化二进制文件大小"
75
+ fi
76
+ else
77
+ echo "✗ 错误: 未找到构建产物: $source_binary"
78
+ return 1
79
+ fi
80
+ }
81
+
82
+ # 构建所有目标
83
+ for target_info in "${TARGETS[@]}"; do
84
+ IFS='|' read -r target platform <<< "$target_info"
85
+
86
+ build_target "$target" "$platform" || echo "跳过 $target(构建失败或平台不支持)"
87
+ done
88
+
89
+ echo ""
90
+ echo "=========================================="
91
+ echo "构建完成!"
92
+ echo "二进制文件位置: $PLATFORMS_DIR"
93
+ echo "=========================================="
94
+
@@ -0,0 +1,90 @@
1
+ #!/bin/bash
2
+
3
+ # 本地构建脚本 - 仅构建当前平台的二进制文件
4
+
5
+ set -e
6
+
7
+ echo "开始构建当前平台的二进制文件..."
8
+
9
+ # 获取项目根目录
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
12
+ PLATFORMS_DIR="$PROJECT_ROOT/platforms"
13
+
14
+ # 创建 platforms 目录
15
+ mkdir -p "$PLATFORMS_DIR"
16
+
17
+ # 检测当前平台
18
+ OS=$(uname -s | tr '[:upper:]' '[:lower:]')
19
+ ARCH=$(uname -m)
20
+
21
+ # 确定目标平台
22
+ case "$OS" in
23
+ darwin)
24
+ if [ "$ARCH" = "arm64" ] || [ "$ARCH" = "aarch64" ]; then
25
+ TARGET="aarch64-apple-darwin"
26
+ PLATFORM="darwin-arm64"
27
+ else
28
+ TARGET="x86_64-apple-darwin"
29
+ PLATFORM="darwin-x64"
30
+ fi
31
+ BINARY_NAME="fnva"
32
+ ;;
33
+ linux)
34
+ if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
35
+ TARGET="aarch64-unknown-linux-gnu"
36
+ PLATFORM="linux-arm64"
37
+ else
38
+ TARGET="x86_64-unknown-linux-gnu"
39
+ PLATFORM="linux-x64"
40
+ fi
41
+ BINARY_NAME="fnva"
42
+ ;;
43
+ *)
44
+ echo "错误: 不支持的操作系统: $OS"
45
+ echo "请使用 GitHub Actions 构建其他平台"
46
+ exit 1
47
+ ;;
48
+ esac
49
+
50
+ echo "检测到平台: $OS ($ARCH)"
51
+ echo "目标平台: $TARGET"
52
+ echo "平台目录: $PLATFORM"
53
+
54
+ # 构建
55
+ echo ""
56
+ echo "开始构建..."
57
+ cargo build --release --target "$TARGET"
58
+
59
+ # 准备输出目录
60
+ OUTPUT_DIR="$PLATFORMS_DIR/$PLATFORM"
61
+ mkdir -p "$OUTPUT_DIR"
62
+
63
+ # 复制二进制文件
64
+ SOURCE_BINARY="$PROJECT_ROOT/target/$TARGET/release/$BINARY_NAME"
65
+ if [ -f "$SOURCE_BINARY" ]; then
66
+ cp "$SOURCE_BINARY" "$OUTPUT_DIR/$BINARY_NAME"
67
+ echo "✓ 成功构建: $OUTPUT_DIR/$BINARY_NAME"
68
+
69
+ # 优化二进制文件大小
70
+ if command -v strip &> /dev/null; then
71
+ strip "$OUTPUT_DIR/$BINARY_NAME"
72
+ echo "✓ 已优化二进制文件大小"
73
+ fi
74
+
75
+ # 显示文件大小
76
+ ls -lh "$OUTPUT_DIR/$BINARY_NAME"
77
+ else
78
+ echo "✗ 错误: 未找到构建产物: $SOURCE_BINARY"
79
+ exit 1
80
+ fi
81
+
82
+ echo ""
83
+ echo "=========================================="
84
+ echo "构建完成!"
85
+ echo "二进制文件位置: $OUTPUT_DIR/$BINARY_NAME"
86
+ echo "=========================================="
87
+ echo ""
88
+ echo "注意: 此脚本仅构建当前平台。"
89
+ echo "要构建所有平台,请使用 GitHub Actions 或运行 scripts/build-all.sh"
90
+
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const { spawn } = require('child_process');
7
+
8
+ function detectShell() {
9
+ if (process.platform === 'win32') {
10
+ return 'powershell';
11
+ }
12
+ return process.env.SHELL?.split('/').pop() || 'bash';
13
+ }
14
+
15
+ function getShellConfigPath(shell) {
16
+ switch (shell) {
17
+ case 'powershell':
18
+ return path.join(process.env.USERPROFILE || os.homedir(), 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1');
19
+ case 'bash':
20
+ return path.join(os.homedir(), '.bashrc');
21
+ case 'zsh':
22
+ return path.join(os.homedir(), '.zshrc');
23
+ case 'fish':
24
+ return path.join(os.homedir(), '.config', 'fish', 'config.fish');
25
+ default:
26
+ return null;
27
+ }
28
+ }
29
+
30
+ function getPowerShellFunction() {
31
+ return `
32
+ # fnva 自动化函数 - 由 npm 安装自动添加
33
+ function fnva {
34
+ if ($args.Count -ge 2 -and ($args[0] -eq "java" -or $args[0] -eq "llm" -or $args[0] -eq "cc") -and ($args[1] -eq "use")) {
35
+ $tempFile = "$env:TEMP\fnva_script_$(Get-Random).ps1"
36
+
37
+ $env:FNVAAUTOMODE = "1"
38
+ try {
39
+ cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args" | Out-File -FilePath $tempFile -Encoding UTF8
40
+ & $tempFile
41
+ } finally {
42
+ $env:FNVAAUTOMODE = ""
43
+ Remove-Item $tempFile -ErrorAction SilentlyContinue
44
+ }
45
+ } else {
46
+ $env:FNVAAUTOMODE = "1"
47
+ try {
48
+ cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args"
49
+ } finally {
50
+ $env:FNVAAUTOMODE = ""
51
+ }
52
+ }
53
+ }
54
+ `;
55
+ }
56
+
57
+ function getBashFunction() {
58
+ return `
59
+ # fnva 自动化函数 - 由 npm 安装自动添加
60
+ fnva() {
61
+ if [[ \$# -ge 2 && ("\$1" == "java" || "\$1" == "llm" || "\$1" == "cc") && "\$2" == "use" ]]; then
62
+ local temp_file=\$(mktemp)
63
+ chmod +x "\$temp_file"
64
+
65
+ FNVA_AUTO_MODE=1 fnva "\$@" > "\$temp_file"
66
+ source "\$temp_file"
67
+ rm -f "\$temp_file"
68
+ else
69
+ FNVA_AUTO_MODE=1 fnva "\$@"
70
+ fi
71
+ }
72
+ `;
73
+ }
74
+
75
+ function getFishFunction() {
76
+ return `
77
+ # fnva 自动化函数 - 由 npm 安装自动添加
78
+ function fnva
79
+ if test (count \$argv) -ge 2; and string match -q -r "^(java|llm|cc)\$" \$argv[1]; and test \$argv[2] = "use"
80
+ set temp_file (mktemp)
81
+ chmod +x \$temp_file
82
+ env FNVA_AUTO_MODE=1 fnva \$argv > \$temp_file
83
+ source \$temp_file
84
+ rm -f \$temp_file
85
+ else
86
+ env FNVA_AUTO_MODE=1 fnva \$argv
87
+ end
88
+ end
89
+ `;
90
+ }
91
+
92
+ function getShellFunction(shell) {
93
+ switch (shell) {
94
+ case 'powershell':
95
+ return getPowerShellFunction();
96
+ case 'bash':
97
+ return getBashFunction();
98
+ case 'zsh':
99
+ return getBashFunction(); // zsh 使用和 bash 相同的语法
100
+ case 'fish':
101
+ return getFishFunction();
102
+ default:
103
+ return '';
104
+ }
105
+ }
106
+
107
+ function isFunctionInstalled(configPath, shell) {
108
+ if (!fs.existsSync(configPath)) {
109
+ return false;
110
+ }
111
+
112
+ const content = fs.readFileSync(configPath, 'utf8');
113
+ return content.includes('fnva 自动化函数 - 由 npm 安装自动添加');
114
+ }
115
+
116
+ function installShellIntegration() {
117
+ const shell = detectShell();
118
+ const configPath = getShellConfigPath(shell);
119
+
120
+ if (!configPath) {
121
+ console.log(`❌ 不支持的 shell: ${shell}`);
122
+ console.log('请手动配置 fnva,详见: https://github.com/your-repo/fnva');
123
+ return false;
124
+ }
125
+
126
+ if (isFunctionInstalled(configPath, shell)) {
127
+ console.log(`✅ fnva shell 集成已安装在: ${configPath}`);
128
+ return true;
129
+ }
130
+
131
+ try {
132
+ // 确保目录存在
133
+ const dir = path.dirname(configPath);
134
+ if (!fs.existsSync(dir)) {
135
+ fs.mkdirSync(dir, { recursive: true });
136
+ }
137
+
138
+ // 获取函数定义
139
+ const functionCode = getShellFunction(shell);
140
+
141
+ // 添加到配置文件
142
+ if (fs.existsSync(configPath)) {
143
+ const content = fs.readFileSync(configPath, 'utf8');
144
+ fs.writeFileSync(configPath, content + '\n' + functionCode);
145
+ } else {
146
+ fs.writeFileSync(configPath, functionCode);
147
+ }
148
+
149
+ console.log(`✅ fnva shell 集成已安装到: ${configPath}`);
150
+ console.log('🔄 请重新加载你的 shell 配置:');
151
+
152
+ switch (shell) {
153
+ case 'powershell':
154
+ console.log(' . $PROFILE');
155
+ break;
156
+ case 'bash':
157
+ console.log(' source ~/.bashrc');
158
+ break;
159
+ case 'zsh':
160
+ console.log(' source ~/.zshrc');
161
+ break;
162
+ case 'fish':
163
+ console.log(' source ~/.config/fish/config.fish');
164
+ break;
165
+ }
166
+
167
+ return true;
168
+ } catch (error) {
169
+ console.log(`❌ 安装失败: ${error.message}`);
170
+ console.log('请手动配置 fnva');
171
+ return false;
172
+ }
173
+ }
174
+
175
+ // 询问用户是否安装
176
+ function promptInstallation() {
177
+ if (process.env.FNVA_SKIP_SHELL_SETUP === '1') {
178
+ console.log('⏭️ 跳过 shell 集成安装');
179
+ return;
180
+ }
181
+
182
+ const shell = detectShell();
183
+ console.log(`🔧 检测到 shell: ${shell}`);
184
+ console.log('🚀 是否安装 fnva shell 集成? (y/N)');
185
+
186
+ process.stdin.resume();
187
+ process.stdin.setEncoding('utf8');
188
+
189
+ process.stdin.on('data', function(data) {
190
+ const response = data.toString().trim().toLowerCase();
191
+ if (response === 'y' || response === 'yes') {
192
+ installShellIntegration();
193
+ } else {
194
+ console.log('⏭️ 跳过 shell 集成安装');
195
+ console.log('📖 手动配置指南: https://github.com/your-repo/fnva');
196
+ }
197
+ process.exit(0);
198
+ });
199
+
200
+ // 10秒后自动跳过
201
+ setTimeout(() => {
202
+ console.log('⏭️ 超时,跳过 shell 集成安装');
203
+ console.log('📖 手动配置指南: https://github.com/your-repo/fnva');
204
+ process.exit(0);
205
+ }, 10000);
206
+ }
207
+
208
+ // 主程序
209
+ if (require.main === module) {
210
+ console.log('🔧 fnva shell 集成安装器');
211
+ console.log(`📍 Node.js 进程ID: ${process.pid}`);
212
+ console.log(`📂 工作目录: ${process.cwd()}`);
213
+ console.log(`🎯 参数: ${process.argv.join(' ')}`);
214
+
215
+ if (process.argv.includes('--auto') || process.argv.includes('--yes')) {
216
+ console.log('🚀 自动模式启动安装...');
217
+ const result = installShellIntegration();
218
+ console.log(`🏁 安装结果: ${result ? '成功' : '失败'}`);
219
+ } else {
220
+ promptInstallation();
221
+ }
222
+ }
223
+
224
+ module.exports = {
225
+ detectShell,
226
+ getShellConfigPath,
227
+ getShellFunction,
228
+ isFunctionInstalled,
229
+ installShellIntegration
230
+ };
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+
3
+ # 发布前准备脚本
4
+
5
+ set -e
6
+
7
+ echo "准备发布 npm 包..."
8
+
9
+ # 检查必要的文件
10
+ REQUIRED_FILES=(
11
+ "package.json"
12
+ "bin/fnva"
13
+ "README.md"
14
+ )
15
+
16
+ for file in "${REQUIRED_FILES[@]}"; do
17
+ if [ ! -f "$file" ]; then
18
+ echo "错误: 缺少必需文件: $file"
19
+ exit 1
20
+ fi
21
+ done
22
+
23
+ # 检查版本号
24
+ echo "检查版本号..."
25
+ VERSION=$(node -p "require('./package.json').version")
26
+ echo "当前版本: $VERSION"
27
+
28
+ # 在 CI/CD 环境中跳过平台二进制文件检查和交互式确认
29
+ if [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; then
30
+ echo "CI/CD 环境: 跳过构建检查,自动确认发布版本 $VERSION"
31
+ echo "平台二进制文件将在发布时包含"
32
+ else
33
+ # 本地环境: 检查平台二进制文件
34
+ if [ ! -d "platforms" ] || [ -z "$(ls -A platforms 2>/dev/null)" ]; then
35
+ echo "警告: platforms 目录为空或不存在"
36
+ echo "请先运行 'npm run build' 或 'npm run build:all' 构建二进制文件"
37
+ exit 1
38
+ fi
39
+
40
+ # 本地环境: 提示用户确认
41
+ read -p "确认发布版本 $VERSION? (y/N) " -n 1 -r
42
+ echo
43
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
44
+ echo "已取消发布"
45
+ exit 1
46
+ fi
47
+ fi
48
+
49
+ echo "准备完成,准备发布到 NPM"
50
+
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ function detectShell() {
8
+ if (process.platform === 'win32') {
9
+ return 'powershell';
10
+ }
11
+ return process.env.SHELL?.split('/').pop() || 'bash';
12
+ }
13
+
14
+ function getShellConfigPath(shell) {
15
+ switch (shell) {
16
+ case 'powershell':
17
+ return path.join(process.env.USERPROFILE || os.homedir(), 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1');
18
+ case 'bash':
19
+ return path.join(os.homedir(), '.bashrc');
20
+ case 'zsh':
21
+ return path.join(os.homedir(), '.zshrc');
22
+ case 'fish':
23
+ return path.join(os.homedir(), '.config', 'fish', 'config.fish');
24
+ default:
25
+ return null;
26
+ }
27
+ }
28
+
29
+ function removeShellIntegration(configPath, shell) {
30
+ if (!fs.existsSync(configPath)) {
31
+ console.log(`⚠️ 配置文件不存在: ${configPath}`);
32
+ return false;
33
+ }
34
+
35
+ try {
36
+ let content = fs.readFileSync(configPath, 'utf8');
37
+ const originalContent = content;
38
+
39
+ // 方法1: 查找标记,精确删除整个函数块
40
+ const marker = '# fnva 自动化函数 - 由 npm 安装自动添加';
41
+ const startIndex = content.indexOf(marker);
42
+
43
+ if (startIndex !== -1) {
44
+ // 找到标记前的换行符
45
+ const beforeMarker = content.substring(0, startIndex).trimEnd();
46
+
47
+ // 从标记开始查找完整的函数
48
+ const afterMarker = content.substring(startIndex);
49
+ const lines = afterMarker.split('\n');
50
+
51
+ let functionEndIndex = -1;
52
+ let braceCount = 0;
53
+ let foundFunction = false;
54
+
55
+ for (let i = 0; i < lines.length; i++) {
56
+ const line = lines[i];
57
+ if (line.includes('function fnva') || line.includes('fnva(')) {
58
+ foundFunction = true;
59
+ }
60
+
61
+ if (foundFunction) {
62
+ // 计算大括号
63
+ for (const char of line) {
64
+ if (char === '{') braceCount++;
65
+ if (char === '}') braceCount--;
66
+ }
67
+
68
+ // 当大括号平衡时,函数结束
69
+ if (braceCount === 0) {
70
+ functionEndIndex = i + 1;
71
+ break;
72
+ }
73
+ }
74
+ }
75
+
76
+ if (functionEndIndex !== -1) {
77
+ // 重建内容
78
+ const afterFunction = lines.slice(functionEndIndex).join('\n');
79
+ content = beforeMarker + '\n' + afterFunction;
80
+ } else {
81
+ console.log('⚠️ 无法确定函数结束位置');
82
+ return false;
83
+ }
84
+ }
85
+
86
+ // 方法2: 如果没找到标记,使用正则表达式清理任何 fnva 相关内容
87
+ if (content === originalContent) {
88
+ // 使用正则表达式删除任何包含 fnva 的行和相关的环境变量处理
89
+ content = content
90
+ // 删除标记到函数结束的所有内容
91
+ .replace(/# fnva 自动化函数 - 由 npm 安装自动添加[\s\S]*?(?=\n\S|\n$)/g, '')
92
+ // 删除剩余的 fnva 相关行
93
+ .replace(/.*fnva.*\n?/g, '')
94
+ // 删除 FNVAAUTOMODE 相关行
95
+ .replace(/.*FNVAAUTOMODE.*\n?/g, '')
96
+ // 删除 cmd.exe 调用 fnva 的行
97
+ .replace(/.*cmd\.exe.*fnva.*\n?/g, '')
98
+ // 清理多余的空行
99
+ .replace(/\n{3,}/g, '\n\n')
100
+ .trim() + '\n';
101
+ }
102
+
103
+ // 如果内容有变化,写入文件
104
+ if (content !== originalContent) {
105
+ fs.writeFileSync(configPath, content);
106
+ console.log(`✅ fnva shell 集成已从 ${configPath} 移除`);
107
+ return true;
108
+ } else {
109
+ console.log('⚠️ 未找到需要清理的内容');
110
+ return false;
111
+ }
112
+ } catch (error) {
113
+ console.log(`❌ 移除失败: ${error.message}`);
114
+ return false;
115
+ }
116
+ }
117
+
118
+ function main() {
119
+ console.log('🔧 fnva shell 集成卸载器');
120
+
121
+ const shell = detectShell();
122
+ const configPath = getShellConfigPath(shell);
123
+
124
+ if (!configPath) {
125
+ console.log(`❌ 不支持的 shell: ${shell}`);
126
+ return;
127
+ }
128
+
129
+ const success = removeShellIntegration(configPath, shell);
130
+
131
+ if (success) {
132
+ console.log('🔄 请重新加载你的 shell 配置:');
133
+
134
+ switch (shell) {
135
+ case 'powershell':
136
+ console.log(' . $PROFILE');
137
+ break;
138
+ case 'bash':
139
+ console.log(' source ~/.bashrc');
140
+ break;
141
+ case 'zsh':
142
+ console.log(' source ~/.zshrc');
143
+ break;
144
+ case 'fish':
145
+ console.log(' source ~/.config/fish/config.fish');
146
+ break;
147
+ }
148
+ }
149
+ }
150
+
151
+ if (require.main === module) {
152
+ main();
153
+ }
154
+
155
+ module.exports = {
156
+ detectShell,
157
+ getShellConfigPath,
158
+ removeShellIntegration
159
+ };