fnva 0.0.24 → 0.0.26

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fnva",
3
- "version": "0.0.24",
3
+ "version": "0.0.26",
4
4
  "description": "跨平台环境切换工具,支持 Java 和 LLM 环境配置",
5
5
  "author": "protagonistss",
6
6
  "license": "MIT",
@@ -14,7 +14,8 @@
14
14
  "uninstall-shell": "node scripts/uninstall-shell-integration.js",
15
15
  "build": "scripts/build-local.sh",
16
16
  "build:all": "scripts/build-all.sh",
17
- "check-permissions": "node scripts/check-permissions.js"
17
+ "check-permissions": "node scripts/check-permissions.js",
18
+ "postuninstall": "echo 'Uninstalling fnva shell integration...' && node scripts/uninstall-shell-integration.js"
18
19
  },
19
20
  "files": [
20
21
  "bin/",
package/platforms/fnva CHANGED
Binary file
Binary file
@@ -77,11 +77,11 @@ fnva() {
77
77
  local temp_file=\$(mktemp)
78
78
  chmod +x "\$temp_file"
79
79
 
80
- FNVA_AUTO_MODE=1 fnva "\$@" > "\$temp_file"
80
+ FNVA_AUTO_MODE=1 command fnva "\$@" > "\$temp_file"
81
81
  source "\$temp_file"
82
82
  rm -f "\$temp_file"
83
83
  else
84
- FNVA_AUTO_MODE=1 fnva "\$@"
84
+ FNVA_AUTO_MODE=1 command fnva "\$@"
85
85
  fi
86
86
  }
87
87
  `;
@@ -94,11 +94,11 @@ function fnva
94
94
  if test (count \$argv) -ge 2; and string match -q -r "^(java|llm|cc)\$" \$argv[1]; and test \$argv[2] = "use"
95
95
  set temp_file (mktemp)
96
96
  chmod +x \$temp_file
97
- env FNVA_AUTO_MODE=1 fnva \$argv > \$temp_file
97
+ env FNVA_AUTO_MODE=1 command fnva \$argv > \$temp_file
98
98
  source \$temp_file
99
99
  rm -f \$temp_file
100
100
  else
101
- env FNVA_AUTO_MODE=1 fnva \$argv
101
+ env FNVA_AUTO_MODE=1 command fnva \$argv
102
102
  end
103
103
  end
104
104
  `;
@@ -242,4 +242,4 @@ module.exports = {
242
242
  getShellFunction,
243
243
  isFunctionInstalled,
244
244
  installShellIntegration
245
- };
245
+ };
@@ -11,126 +11,121 @@ function detectShell() {
11
11
  return process.env.SHELL?.split('/').pop() || 'bash';
12
12
  }
13
13
 
14
- function getShellConfigPath(shell) {
14
+ function getShellConfigPaths(shell) {
15
15
  switch (shell) {
16
16
  case 'powershell':
17
- return path.join(process.env.USERPROFILE || os.homedir(), 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1');
17
+ return [path.join(process.env.USERPROFILE || os.homedir(), 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1')];
18
18
  case 'bash':
19
- return path.join(os.homedir(), '.bashrc');
19
+ return [path.join(os.homedir(), '.bashrc')];
20
20
  case 'zsh':
21
- return path.join(os.homedir(), '.zshrc');
21
+ return [
22
+ path.join(os.homedir(), '.zshrc'),
23
+ path.join(os.homedir(), '.oh-my-zsh', 'custom', '.zshrc'),
24
+ ];
22
25
  case 'fish':
23
- return path.join(os.homedir(), '.config', 'fish', 'config.fish');
26
+ return [path.join(os.homedir(), '.config', 'fish', 'config.fish')];
24
27
  default:
25
- return null;
28
+ return [];
26
29
  }
27
30
  }
28
31
 
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;
32
+ function cleanConfigFile(cfgPath) {
33
+ let content = fs.readFileSync(cfgPath, 'utf8');
34
+ const originalContent = content;
38
35
 
39
- // 方法1: 查找标记,精确删除整个函数块
40
- const marker = '# fnva 自动化函数 - 由 npm 安装自动添加';
41
- const startIndex = content.indexOf(marker);
36
+ const marker = '# fnva 自动化函数 - 用 npm 安装自动添加';
37
+ const startIndex = content.indexOf(marker);
42
38
 
43
- if (startIndex !== -1) {
44
- // 找到标记前的换行符
45
- const beforeMarker = content.substring(0, startIndex).trimEnd();
39
+ if (startIndex !== -1) {
40
+ const beforeMarker = content.substring(0, startIndex).trimEnd();
41
+ const afterMarker = content.substring(startIndex);
42
+ const lines = afterMarker.split('\n');
46
43
 
47
- // 从标记开始查找完整的函数
48
- const afterMarker = content.substring(startIndex);
49
- const lines = afterMarker.split('\n');
44
+ let functionEndIndex = -1;
45
+ let braceCount = 0;
46
+ let foundFunction = false;
50
47
 
51
- let functionEndIndex = -1;
52
- let braceCount = 0;
53
- let foundFunction = false;
48
+ for (let i = 0; i < lines.length; i++) {
49
+ const line = lines[i];
50
+ if (line.includes('function fnva') || line.includes('fnva(')) {
51
+ foundFunction = true;
52
+ }
54
53
 
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;
54
+ if (foundFunction) {
55
+ for (const char of line) {
56
+ if (char === '{') braceCount++;
57
+ if (char === '}') braceCount--;
59
58
  }
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
- }
59
+ if (braceCount === 0) {
60
+ functionEndIndex = i + 1;
61
+ break;
73
62
  }
74
63
  }
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
64
  }
85
65
 
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';
66
+ if (functionEndIndex !== -1) {
67
+ const afterFunction = lines.slice(functionEndIndex).join('\n');
68
+ content = beforeMarker + '\n' + afterFunction;
101
69
  }
70
+ }
71
+
72
+ // 正则兜底:移除残留 fnva 片段
73
+ if (content === originalContent) {
74
+ content = content
75
+ .replace(/# fnva 自动化函数 - 用 npm 安装自动添加[\s\S]*?(?=\n\S|\n$)/g, '')
76
+ .replace(/.*fnva.*\n?/g, '')
77
+ .replace(/.*FNVAAUTOMODE.*\n?/g, '')
78
+ .replace(/.*cmd\.exe.*fnva.*\n?/g, '')
79
+ .replace(/\n{3,}/g, '\n\n')
80
+ .trim() + '\n';
81
+ }
82
+
83
+ if (content !== originalContent) {
84
+ fs.writeFileSync(cfgPath, content);
85
+ console.log(`✅ fnva shell 集成已从 ${cfgPath} 移除`);
86
+ return true;
87
+ }
88
+
89
+ console.log(`⚠️ 未在 ${cfgPath} 找到需要清理的内容`);
90
+ return false;
91
+ }
102
92
 
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;
93
+ function removeShellIntegration(configPath, shell) {
94
+ const paths = getShellConfigPaths(shell);
95
+ if (configPath) paths.unshift(configPath); // 兼容传入单一路径
96
+
97
+ let removedAny = false;
98
+ for (const cfgPath of paths) {
99
+ if (!cfgPath || !fs.existsSync(cfgPath)) continue;
100
+ try {
101
+ const removed = cleanConfigFile(cfgPath);
102
+ removedAny = removedAny || removed;
103
+ } catch (error) {
104
+ console.log(`❌ 移除失败 (${cfgPath}): ${error.message}`);
111
105
  }
112
- } catch (error) {
113
- console.log(`❌ 移除失败: ${error.message}`);
114
- return false;
115
106
  }
107
+
108
+ if (!removedAny) {
109
+ console.log('⚠️ 未找到可清理的 shell 配置文件或未匹配到 fnva 片段');
110
+ }
111
+ return removedAny;
116
112
  }
117
113
 
118
114
  function main() {
119
- console.log('🔧 fnva shell 集成卸载器');
115
+ console.log('🧹 fnva shell 集成卸载');
120
116
 
121
117
  const shell = detectShell();
122
- const configPath = getShellConfigPath(shell);
118
+ const paths = getShellConfigPaths(shell);
123
119
 
124
- if (!configPath) {
125
- console.log(`❌ 不支持的 shell: ${shell}`);
120
+ if (paths.length === 0) {
121
+ console.log(`⚠️ 不支持的 shell: ${shell}`);
126
122
  return;
127
123
  }
128
124
 
129
- const success = removeShellIntegration(configPath, shell);
125
+ const success = removeShellIntegration(null, shell);
130
126
 
131
127
  if (success) {
132
128
  console.log('🔄 请重新加载你的 shell 配置:');
133
-
134
129
  switch (shell) {
135
130
  case 'powershell':
136
131
  console.log(' . $PROFILE');
@@ -154,6 +149,6 @@ if (require.main === module) {
154
149
 
155
150
  module.exports = {
156
151
  detectShell,
157
- getShellConfigPath,
158
- removeShellIntegration
159
- };
152
+ getShellConfigPaths,
153
+ removeShellIntegration,
154
+ };