fnva 0.0.27 → 0.0.28
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
package/platforms/fnva
CHANGED
|
Binary file
|
package/platforms/fnva.exe
CHANGED
|
Binary file
|
|
@@ -2,130 +2,81 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*/
|
|
10
|
-
function ensureExecutablePermissions() {
|
|
11
|
-
try {
|
|
12
|
-
const scriptDir = __dirname;
|
|
13
|
-
const projectRoot = path.resolve(scriptDir, '..');
|
|
14
|
-
const platformsDir = path.join(projectRoot, 'platforms');
|
|
15
|
-
|
|
16
|
-
console.log('✅ Ensuring fnva binary permissions...');
|
|
7
|
+
function log(msg) {
|
|
8
|
+
console.log(msg);
|
|
9
|
+
}
|
|
17
10
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
function ensureExecutable(filePath, label) {
|
|
12
|
+
try {
|
|
13
|
+
const stats = fs.statSync(filePath);
|
|
14
|
+
const hasExec = (stats.mode & 0o111) !== 0;
|
|
15
|
+
log(`Checking ${label}: ${filePath}`);
|
|
16
|
+
log(` Current permissions: ${(stats.mode & 0o777).toString(8)}`);
|
|
17
|
+
|
|
18
|
+
if (!hasExec) {
|
|
19
|
+
fs.chmodSync(filePath, 0o755);
|
|
20
|
+
const newStats = fs.statSync(filePath);
|
|
21
|
+
log(` Updated permissions: ${(newStats.mode & 0o777).toString(8)}`);
|
|
22
|
+
} else {
|
|
23
|
+
log(' Executable bit already set');
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 确保指定路径的二进制文件具有可执行权限,并做一次简单的运行测试
|
|
34
|
-
*/
|
|
35
|
-
function ensureExecutable(binaryPath, label) {
|
|
36
|
-
try {
|
|
37
|
-
const stats = fs.statSync(binaryPath);
|
|
38
|
-
const hasExecPermission = (stats.mode & 0o111) !== 0;
|
|
39
|
-
|
|
40
|
-
console.log(`📍 Checking binary (${label}): ${binaryPath}`);
|
|
41
|
-
console.log(` Current permissions: ${(stats.mode & 0o777).toString(8)}`);
|
|
42
|
-
|
|
43
|
-
if (!hasExecPermission) {
|
|
44
|
-
console.log('🔧 Setting executable permissions...');
|
|
45
|
-
fs.chmodSync(binaryPath, 0o755); // rwxr-xr-x
|
|
46
|
-
|
|
47
|
-
const newStats = fs.statSync(binaryPath);
|
|
48
|
-
const newHasExecPermission = (newStats.mode & 0o111) !== 0;
|
|
49
|
-
|
|
50
|
-
if (newHasExecPermission) {
|
|
51
|
-
console.log(`✅ Successfully set executable permissions (${label})`);
|
|
52
|
-
} else {
|
|
53
|
-
console.log(`❌ Failed to set executable permissions (${label})`);
|
|
54
|
-
console.log(` New permissions: ${(newStats.mode & 0o777).toString(8)}`);
|
|
55
|
-
console.log(` Manual fix may be required: chmod +x "${binaryPath}"`);
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
console.log(`✅ fnva binary already has executable permissions (${label})`);
|
|
59
|
-
}
|
|
26
|
+
const res = spawnSync(filePath, ['--version'], { encoding: 'utf8', timeout: 3000, stdio: 'pipe' });
|
|
27
|
+
if (res.error && res.error.code === 'EACCES') {
|
|
28
|
+
log('WARNING: still not executable; please chmod +x manually');
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
log(`WARNING: could not ensure permissions for ${label}: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
60
34
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
encoding: 'utf8',
|
|
66
|
-
timeout: 3000,
|
|
67
|
-
stdio: 'pipe',
|
|
68
|
-
});
|
|
35
|
+
function ensureExecutablePermissions() {
|
|
36
|
+
const scriptDir = __dirname;
|
|
37
|
+
const projectRoot = path.resolve(scriptDir, '..');
|
|
38
|
+
const platformsDir = path.join(projectRoot, 'platforms');
|
|
69
39
|
|
|
70
|
-
|
|
71
|
-
console.log('✅ fnva binary is executable and responding');
|
|
72
|
-
} else if (testResult.error && testResult.error.code === 'EACCES') {
|
|
73
|
-
console.log('❌ fnva binary still has permission issues');
|
|
74
|
-
console.log(` Manual fix required: chmod +x "${binaryPath}"`);
|
|
75
|
-
}
|
|
76
|
-
} catch {
|
|
77
|
-
// 测试失败不视为致命错误,可能是二进制本身的问题
|
|
78
|
-
}
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.warn(`⚠️ Could not fix binary permissions (${label}): ${error.message}`);
|
|
81
|
-
console.log(` Manual fix required: chmod +x "${binaryPath}"`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
40
|
+
log('Ensuring fnva binary permissions...');
|
|
84
41
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// 优先处理新的平台子目录结构: platforms/<platform>-<arch>/fnva
|
|
90
|
-
ensureExecutable(archBinaryPath, platformDir);
|
|
91
|
-
} else if (fs.existsSync(flatBinaryPath)) {
|
|
92
|
-
// 兼容旧版本扁平结构: platforms/fnva
|
|
93
|
-
console.log('ℹ️ Platform-specific binary not found, falling back to legacy flat layout');
|
|
94
|
-
ensureExecutable(flatBinaryPath, 'platforms/fnva');
|
|
95
|
-
} else {
|
|
96
|
-
console.log(`❌ Binary not found: ${archBinaryPath}`);
|
|
97
|
-
console.log(` Also checked legacy path: ${flatBinaryPath}`);
|
|
98
|
-
console.log(' This might indicate an incomplete installation');
|
|
99
|
-
}
|
|
42
|
+
if (!fs.existsSync(platformsDir)) {
|
|
43
|
+
log('Info: no platforms directory found; skipping (dev install)');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
100
46
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
47
|
+
const platform = process.platform;
|
|
48
|
+
const arch = process.arch === 'arm64' ? 'arm64' : 'x64';
|
|
49
|
+
const platformDir = `${platform}-${arch}`;
|
|
50
|
+
const binaryName = platform === 'win32' ? 'fnva.exe' : 'fnva';
|
|
51
|
+
const archBinaryPath = path.join(platformsDir, platformDir, binaryName);
|
|
52
|
+
const flatBinaryPath = path.join(platformsDir, binaryName);
|
|
106
53
|
|
|
107
|
-
|
|
108
|
-
|
|
54
|
+
if (platform === 'win32') {
|
|
55
|
+
log('Info: Windows detected; chmod not required; skipping permission changes');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
109
58
|
|
|
110
|
-
|
|
111
|
-
|
|
59
|
+
if (fs.existsSync(archBinaryPath)) {
|
|
60
|
+
ensureExecutable(archBinaryPath, platformDir);
|
|
61
|
+
} else if (fs.existsSync(flatBinaryPath)) {
|
|
62
|
+
log('Info: falling back to legacy platforms/fnva layout');
|
|
63
|
+
ensureExecutable(flatBinaryPath, 'platforms/fnva');
|
|
64
|
+
} else {
|
|
65
|
+
log(`Warning: binary not found: ${archBinaryPath}`);
|
|
66
|
+
log(` Also checked: ${flatBinaryPath}`);
|
|
67
|
+
}
|
|
112
68
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
} catch {
|
|
121
|
-
console.log('ℹ️ Could not verify global installation');
|
|
69
|
+
if (process.env.npm_config_global === 'true') {
|
|
70
|
+
try {
|
|
71
|
+
const which = spawnSync('which', ['fnva'], { encoding: 'utf8' });
|
|
72
|
+
const globalPath = which.stdout?.trim();
|
|
73
|
+
if (globalPath && fs.existsSync(globalPath)) {
|
|
74
|
+
ensureExecutable(globalPath, 'global fnva');
|
|
122
75
|
}
|
|
76
|
+
} catch {
|
|
77
|
+
// ignore
|
|
123
78
|
}
|
|
124
|
-
} catch (error) {
|
|
125
|
-
console.warn(`⚠️ Permission check failed: ${error.message}`);
|
|
126
79
|
}
|
|
127
80
|
}
|
|
128
81
|
|
|
129
|
-
|
|
130
|
-
ensureExecutablePermissions();
|
|
131
|
-
|
|
82
|
+
ensureExecutablePermissions();
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Shell integration installer for fnva (npm postinstall helper).
|
|
4
|
+
// Generates a lightweight function wrapper per shell that calls the real
|
|
5
|
+
// `fnva` binary and applies environment switch scripts.
|
|
2
6
|
|
|
3
7
|
const fs = require('fs');
|
|
4
8
|
const path = require('path');
|
|
@@ -14,7 +18,12 @@ function detectShell() {
|
|
|
14
18
|
function getShellConfigPath(shell) {
|
|
15
19
|
switch (shell) {
|
|
16
20
|
case 'powershell':
|
|
17
|
-
return path.join(
|
|
21
|
+
return path.join(
|
|
22
|
+
process.env.USERPROFILE || os.homedir(),
|
|
23
|
+
'Documents',
|
|
24
|
+
'WindowsPowerShell',
|
|
25
|
+
'Microsoft.PowerShell_profile.ps1'
|
|
26
|
+
);
|
|
18
27
|
case 'bash':
|
|
19
28
|
return path.join(os.homedir(), '.bashrc');
|
|
20
29
|
case 'zsh':
|
|
@@ -28,41 +37,28 @@ function getShellConfigPath(shell) {
|
|
|
28
37
|
|
|
29
38
|
function getPowerShellFunction() {
|
|
30
39
|
return `
|
|
31
|
-
# fnva
|
|
40
|
+
# fnva auto integration (added by npm install)
|
|
32
41
|
function fnva {
|
|
33
42
|
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
43
|
$tempFile = Join-Path $env:TEMP ("fnva_script_" + (Get-Random) + ".ps1")
|
|
35
44
|
|
|
36
45
|
$env:FNVAAUTOMODE = "1"
|
|
37
46
|
try {
|
|
38
|
-
# 捕获 fnva 输出并保存到临时文件
|
|
39
47
|
$output = cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args" 2>&1
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
if ($output -match '\$env:' -or $output -match 'Write-Host') {
|
|
49
|
+
if ($output -match '\\$env:' -or $output -match 'Write-Host') {
|
|
43
50
|
$output | Out-File -FilePath $tempFile -Encoding UTF8
|
|
44
|
-
try {
|
|
45
|
-
& $tempFile
|
|
46
|
-
} catch {
|
|
47
|
-
Write-Host "执行脚本时出错: $_" -ForegroundColor Red
|
|
48
|
-
}
|
|
51
|
+
try { & $tempFile } catch { Write-Host "Error executing script: $_" -ForegroundColor Red }
|
|
49
52
|
} else {
|
|
50
|
-
# 如果不是脚本内容,直接输出
|
|
51
53
|
$output
|
|
52
54
|
}
|
|
53
55
|
} finally {
|
|
54
56
|
$env:FNVAAUTOMODE = ""
|
|
55
|
-
if (Test-Path $tempFile) {
|
|
56
|
-
Remove-Item $tempFile -ErrorAction SilentlyContinue
|
|
57
|
-
}
|
|
57
|
+
if (Test-Path $tempFile) { Remove-Item $tempFile -ErrorAction SilentlyContinue }
|
|
58
58
|
}
|
|
59
59
|
} else {
|
|
60
60
|
$env:FNVAAUTOMODE = "1"
|
|
61
|
-
try {
|
|
62
|
-
cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args"
|
|
63
|
-
} finally {
|
|
64
|
-
$env:FNVAAUTOMODE = ""
|
|
65
|
-
}
|
|
61
|
+
try { cmd.exe /c "set FNVA_AUTO_MODE=%FNVAAUTOMODE% && fnva $args" } finally { $env:FNVAAUTOMODE = "" }
|
|
66
62
|
}
|
|
67
63
|
}
|
|
68
64
|
`;
|
|
@@ -70,7 +66,7 @@ function fnva {
|
|
|
70
66
|
|
|
71
67
|
function getBashFunction() {
|
|
72
68
|
return `
|
|
73
|
-
# fnva
|
|
69
|
+
# fnva auto integration (added by npm install)
|
|
74
70
|
fnva() {
|
|
75
71
|
local __fnva_bin
|
|
76
72
|
__fnva_bin="$(command -v fnva | head -n 1)"
|
|
@@ -96,7 +92,7 @@ fnva() {
|
|
|
96
92
|
|
|
97
93
|
function getFishFunction() {
|
|
98
94
|
return `
|
|
99
|
-
# fnva
|
|
95
|
+
# fnva auto integration (added by npm install)
|
|
100
96
|
function fnva
|
|
101
97
|
set __fnva_bin (command -v fnva | head -n 1)
|
|
102
98
|
if test -z "$__fnva_bin"
|
|
@@ -122,9 +118,8 @@ function getShellFunction(shell) {
|
|
|
122
118
|
case 'powershell':
|
|
123
119
|
return getPowerShellFunction();
|
|
124
120
|
case 'bash':
|
|
125
|
-
return getBashFunction();
|
|
126
121
|
case 'zsh':
|
|
127
|
-
return getBashFunction();
|
|
122
|
+
return getBashFunction();
|
|
128
123
|
case 'fish':
|
|
129
124
|
return getFishFunction();
|
|
130
125
|
default:
|
|
@@ -136,9 +131,8 @@ function isFunctionInstalled(configPath) {
|
|
|
136
131
|
if (!fs.existsSync(configPath)) {
|
|
137
132
|
return false;
|
|
138
133
|
}
|
|
139
|
-
|
|
140
134
|
const content = fs.readFileSync(configPath, 'utf8');
|
|
141
|
-
return content.includes('fnva
|
|
135
|
+
return content.includes('fnva auto integration (added by npm install)');
|
|
142
136
|
}
|
|
143
137
|
|
|
144
138
|
function installShellIntegration() {
|
|
@@ -146,13 +140,13 @@ function installShellIntegration() {
|
|
|
146
140
|
const configPath = getShellConfigPath(shell);
|
|
147
141
|
|
|
148
142
|
if (!configPath) {
|
|
149
|
-
console.log(`⚠️
|
|
150
|
-
console.log('
|
|
143
|
+
console.log(`⚠️ Unsupported shell: ${shell}`);
|
|
144
|
+
console.log('Please configure fnva manually (see README).');
|
|
151
145
|
return false;
|
|
152
146
|
}
|
|
153
147
|
|
|
154
148
|
if (isFunctionInstalled(configPath)) {
|
|
155
|
-
console.log(`✅ fnva shell
|
|
149
|
+
console.log(`✅ fnva shell integration already present: ${configPath}`);
|
|
156
150
|
return true;
|
|
157
151
|
}
|
|
158
152
|
|
|
@@ -171,9 +165,8 @@ function installShellIntegration() {
|
|
|
171
165
|
fs.writeFileSync(configPath, functionCode);
|
|
172
166
|
}
|
|
173
167
|
|
|
174
|
-
console.log(`✅ fnva shell
|
|
175
|
-
console.log('🔄
|
|
176
|
-
|
|
168
|
+
console.log(`✅ fnva shell integration installed at: ${configPath}`);
|
|
169
|
+
console.log('🔄 Reload your shell config:');
|
|
177
170
|
switch (shell) {
|
|
178
171
|
case 'powershell':
|
|
179
172
|
console.log(' . $PROFILE');
|
|
@@ -188,29 +181,28 @@ function installShellIntegration() {
|
|
|
188
181
|
console.log(' source ~/.config/fish/config.fish');
|
|
189
182
|
break;
|
|
190
183
|
}
|
|
191
|
-
|
|
192
184
|
return true;
|
|
193
185
|
} catch (error) {
|
|
194
|
-
console.log(`❌
|
|
195
|
-
console.log('
|
|
186
|
+
console.log(`❌ Install failed: ${error.message}`);
|
|
187
|
+
console.log('Please configure fnva manually (see README).');
|
|
196
188
|
return false;
|
|
197
189
|
}
|
|
198
190
|
}
|
|
199
191
|
|
|
200
192
|
function promptInstallation() {
|
|
201
193
|
if (process.env.FNVA_SKIP_SHELL_SETUP === '1') {
|
|
202
|
-
console.log('⏭️
|
|
194
|
+
console.log('⏭️ Skipping shell integration (FNVA_SKIP_SHELL_SETUP=1)');
|
|
203
195
|
return;
|
|
204
196
|
}
|
|
205
197
|
|
|
206
198
|
const shell = detectShell();
|
|
207
|
-
console.log(`🔍
|
|
208
|
-
console.log('❓
|
|
199
|
+
console.log(`🔍 Detected shell: ${shell}`);
|
|
200
|
+
console.log('❓ Install fnva shell integration? (y/N)');
|
|
209
201
|
|
|
210
202
|
const readline = require('readline');
|
|
211
203
|
const rl = readline.createInterface({
|
|
212
204
|
input: process.stdin,
|
|
213
|
-
output: process.stdout
|
|
205
|
+
output: process.stdout,
|
|
214
206
|
});
|
|
215
207
|
|
|
216
208
|
rl.question('> ', (answer) => {
|
|
@@ -218,21 +210,21 @@ function promptInstallation() {
|
|
|
218
210
|
if (normalized === 'y' || normalized === 'yes') {
|
|
219
211
|
installShellIntegration();
|
|
220
212
|
} else {
|
|
221
|
-
console.log('⏩
|
|
213
|
+
console.log('⏩ Skipped shell integration.');
|
|
222
214
|
}
|
|
223
215
|
rl.close();
|
|
224
216
|
});
|
|
225
217
|
}
|
|
226
218
|
|
|
227
219
|
function main() {
|
|
228
|
-
console.log('🛠️ fnva shell
|
|
229
|
-
console.log(`📦 Node.js
|
|
230
|
-
console.log(`📍
|
|
220
|
+
console.log('🛠️ fnva shell integration installer');
|
|
221
|
+
console.log(`📦 Node.js version: ${process.version}`);
|
|
222
|
+
console.log(`📍 CWD: ${process.cwd()}`);
|
|
231
223
|
|
|
232
224
|
if (process.argv.includes('--auto') || process.argv.includes('--yes')) {
|
|
233
|
-
console.log('🤖
|
|
225
|
+
console.log('🤖 Auto mode: installing...');
|
|
234
226
|
const result = installShellIntegration();
|
|
235
|
-
console.log(`📄
|
|
227
|
+
console.log(`📄 Install result: ${result ? 'success' : 'failed'}`);
|
|
236
228
|
} else {
|
|
237
229
|
promptInstallation();
|
|
238
230
|
}
|
|
@@ -247,5 +239,5 @@ module.exports = {
|
|
|
247
239
|
getShellConfigPath,
|
|
248
240
|
getShellFunction,
|
|
249
241
|
isFunctionInstalled,
|
|
250
|
-
installShellIntegration
|
|
242
|
+
installShellIntegration,
|
|
251
243
|
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// Shell integration uninstaller for fnva (npm postuninstall helper).
|
|
4
|
+
// Cleans fnva wrapper functions from common shell config files.
|
|
5
|
+
|
|
3
6
|
const fs = require('fs');
|
|
4
7
|
const path = require('path');
|
|
5
8
|
const os = require('os');
|
|
6
9
|
|
|
7
10
|
function detectShell() {
|
|
8
|
-
if (process.platform === 'win32')
|
|
9
|
-
return 'powershell';
|
|
10
|
-
}
|
|
11
|
+
if (process.platform === 'win32') return 'powershell';
|
|
11
12
|
return process.env.SHELL?.split('/').pop() || 'bash';
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -33,7 +34,7 @@ function cleanConfigFile(cfgPath) {
|
|
|
33
34
|
let content = fs.readFileSync(cfgPath, 'utf8');
|
|
34
35
|
const originalContent = content;
|
|
35
36
|
|
|
36
|
-
const marker = '# fnva
|
|
37
|
+
const marker = '# fnva auto integration (added by npm install)';
|
|
37
38
|
const startIndex = content.indexOf(marker);
|
|
38
39
|
|
|
39
40
|
if (startIndex !== -1) {
|
|
@@ -69,10 +70,9 @@ function cleanConfigFile(cfgPath) {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
// 正则兜底:移除残留 fnva 片段
|
|
73
73
|
if (content === originalContent) {
|
|
74
74
|
content = content
|
|
75
|
-
.replace(/# fnva
|
|
75
|
+
.replace(/# fnva auto integration \(added by npm install\)[\s\S]*?(?=\n\S|\n$)/g, '')
|
|
76
76
|
.replace(/.*fnva.*\n?/g, '')
|
|
77
77
|
.replace(/.*FNVAAUTOMODE.*\n?/g, '')
|
|
78
78
|
.replace(/.*cmd\.exe.*fnva.*\n?/g, '')
|
|
@@ -82,50 +82,50 @@ function cleanConfigFile(cfgPath) {
|
|
|
82
82
|
|
|
83
83
|
if (content !== originalContent) {
|
|
84
84
|
fs.writeFileSync(cfgPath, content);
|
|
85
|
-
console.log(`✅ fnva shell
|
|
85
|
+
console.log(`✅ fnva shell integration removed from ${cfgPath}`);
|
|
86
86
|
return true;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
console.log(`⚠️
|
|
89
|
+
console.log(`⚠️ No fnva block found in ${cfgPath}`);
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function removeShellIntegration(configPath, shell) {
|
|
94
|
-
const paths = getShellConfigPaths(shell);
|
|
95
|
-
if (configPath) paths.unshift(configPath); // 兼容传入单一路径
|
|
96
|
-
|
|
94
|
+
const paths = configPath ? [configPath] : getShellConfigPaths(shell);
|
|
97
95
|
let removedAny = false;
|
|
96
|
+
|
|
98
97
|
for (const cfgPath of paths) {
|
|
99
98
|
if (!cfgPath || !fs.existsSync(cfgPath)) continue;
|
|
100
99
|
try {
|
|
101
100
|
const removed = cleanConfigFile(cfgPath);
|
|
102
101
|
removedAny = removedAny || removed;
|
|
103
102
|
} catch (error) {
|
|
104
|
-
console.log(`❌
|
|
103
|
+
console.log(`❌ Remove failed (${cfgPath}): ${error.message}`);
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
if (!removedAny) {
|
|
109
|
-
console.log('⚠️
|
|
108
|
+
console.log('⚠️ No shell config cleaned (file missing or no fnva block)');
|
|
110
109
|
}
|
|
110
|
+
|
|
111
111
|
return removedAny;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function main() {
|
|
115
|
-
console.log('🧹 fnva shell
|
|
115
|
+
console.log('🧹 fnva shell integration uninstaller');
|
|
116
116
|
|
|
117
117
|
const shell = detectShell();
|
|
118
118
|
const paths = getShellConfigPaths(shell);
|
|
119
119
|
|
|
120
|
-
if (paths.length
|
|
121
|
-
console.log(`⚠️
|
|
120
|
+
if (!paths.length) {
|
|
121
|
+
console.log(`⚠️ Unsupported shell: ${shell}`);
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const success = removeShellIntegration(null, shell);
|
|
126
126
|
|
|
127
127
|
if (success) {
|
|
128
|
-
console.log('🔄
|
|
128
|
+
console.log('🔄 Reload your shell config:');
|
|
129
129
|
switch (shell) {
|
|
130
130
|
case 'powershell':
|
|
131
131
|
console.log(' . $PROFILE');
|
|
@@ -151,4 +151,4 @@ module.exports = {
|
|
|
151
151
|
detectShell,
|
|
152
152
|
getShellConfigPaths,
|
|
153
153
|
removeShellIntegration,
|
|
154
|
-
};
|
|
154
|
+
};
|