fnva 0.0.7 → 0.0.9
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/bin/fnva.cmd +9 -1
- package/bin/fnva.js +195 -8
- package/bin/fnva.ps1 +9 -1
- package/package.json +1 -1
- package/platforms/fnva +0 -0
- package/platforms/fnva.exe +0 -0
package/bin/fnva.cmd
CHANGED
|
@@ -17,9 +17,17 @@ REM 构建二进制文件路径
|
|
|
17
17
|
set PLATFORM_DIR=%OS%-%ARCH%
|
|
18
18
|
set BINARY_PATH=%~dp0..\platforms\%PLATFORM_DIR%\fnva.exe
|
|
19
19
|
|
|
20
|
+
REM 如果分层结构不存在,尝试扁平结构
|
|
21
|
+
if not exist "%BINARY_PATH%" (
|
|
22
|
+
set BINARY_PATH=%~dp0..\platforms\fnva.exe
|
|
23
|
+
)
|
|
24
|
+
|
|
20
25
|
REM 检查二进制文件是否存在
|
|
21
26
|
if not exist "%BINARY_PATH%" (
|
|
22
|
-
echo 错误:
|
|
27
|
+
echo 错误: 未找到二进制文件
|
|
28
|
+
echo 尝试的路径:
|
|
29
|
+
echo 1. %~dp0..\platforms\%PLATFORM_DIR%\fnva.exe
|
|
30
|
+
echo 2. %~dp0..\platforms\fnva.exe
|
|
23
31
|
echo 请运行 'npm run build' 构建二进制文件
|
|
24
32
|
exit /b 1
|
|
25
33
|
)
|
package/bin/fnva.js
CHANGED
|
@@ -74,6 +74,80 @@ function buildBinaryPath() {
|
|
|
74
74
|
return null;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
function isEnvironmentSwitchCommand(args) {
|
|
78
|
+
return args.length >= 3 &&
|
|
79
|
+
(args[0] === 'java' || args[0] === 'llm' || args[0] === 'cc') &&
|
|
80
|
+
args[1] === 'use';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function hasDirectExecuteFlag(args) {
|
|
84
|
+
return args.includes('--exec') || args.includes('-e');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function parseEnvironmentScript(scriptContent) {
|
|
88
|
+
if (!scriptContent || scriptContent.trim() === '') {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 将数组输出转换为字符串
|
|
93
|
+
if (Array.isArray(scriptContent)) {
|
|
94
|
+
scriptContent = scriptContent.join('\n');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const envVars = {};
|
|
98
|
+
const lines = scriptContent.split('\n');
|
|
99
|
+
|
|
100
|
+
for (const line of lines) {
|
|
101
|
+
const trimmedLine = line.trim();
|
|
102
|
+
|
|
103
|
+
// 解析 PowerShell 环境变量设置
|
|
104
|
+
if (trimmedLine.startsWith('$env:')) {
|
|
105
|
+
const match = trimmedLine.match(/\$env:(\w+)\s*=\s*"([^"]*)"/);
|
|
106
|
+
if (match) {
|
|
107
|
+
envVars[match[1]] = match[2];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 解析 bash/zsh 环境变量设置
|
|
112
|
+
if (trimmedLine.startsWith('export ')) {
|
|
113
|
+
const match = trimmedLine.match(/export\s+(\w+)\s*=\s*"([^"]*)"/);
|
|
114
|
+
if (match) {
|
|
115
|
+
envVars[match[1]] = match[2];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 解析不带引号的环境变量设置
|
|
120
|
+
const unquotedMatch = trimmedLine.match(/\$env:(\w+)\s*=\s*([^;]+)/);
|
|
121
|
+
if (unquotedMatch) {
|
|
122
|
+
envVars[unquotedMatch[1]] = unquotedMatch[2].trim();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return envVars;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function applyEnvironmentVariables(envVars) {
|
|
130
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
131
|
+
process.env[key] = value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function displaySuccessMessage(envType, envName, envVars) {
|
|
136
|
+
console.log(`✅ Switched to ${envType} environment: ${envName}`);
|
|
137
|
+
|
|
138
|
+
if (envVars.JAVA_HOME) {
|
|
139
|
+
console.log(`📁 JAVA_HOME: ${envVars.JAVA_HOME}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (envVars.ANTHROPIC_AUTH_TOKEN) {
|
|
143
|
+
console.log(`🔑 ANTHROPIC_AUTH_TOKEN: [已设置]`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (envVars.OPENAI_API_KEY) {
|
|
147
|
+
console.log(`🔑 OPENAI_API_KEY: [已设置]`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
77
151
|
function run() {
|
|
78
152
|
const binaryPath = buildBinaryPath();
|
|
79
153
|
|
|
@@ -87,16 +161,129 @@ function run() {
|
|
|
87
161
|
process.exit(1);
|
|
88
162
|
}
|
|
89
163
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
});
|
|
164
|
+
const args = process.argv.slice(2);
|
|
165
|
+
const isSwitchCommand = isEnvironmentSwitchCommand(args);
|
|
93
166
|
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
167
|
+
if (isSwitchCommand) {
|
|
168
|
+
const { spawnSync } = require('child_process');
|
|
169
|
+
const result = spawnSync(binaryPath, args, {
|
|
170
|
+
encoding: 'utf8',
|
|
171
|
+
shell: true
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (result.error) {
|
|
175
|
+
console.error(`Failed to execute fnva: ${result.error.message}`);
|
|
176
|
+
process.exit(result.status ?? 1);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (result.status !== 0) {
|
|
180
|
+
process.exit(result.status);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 获取环境切换脚本
|
|
184
|
+
const stdout = result.stdout || '';
|
|
185
|
+
if (stdout.includes('JAVA_HOME') || stdout.includes('ANTHROPIC_') || stdout.includes('OPENAI_')) {
|
|
186
|
+
// 将数组输出转换为字符串
|
|
187
|
+
const script = Array.isArray(stdout) ? stdout.join('\n') : stdout;
|
|
188
|
+
const envType = args[0];
|
|
189
|
+
const envName = args[2];
|
|
190
|
+
|
|
191
|
+
// 在 Windows 上:启动新的 PowerShell 会话并自动执行环境切换
|
|
192
|
+
if (process.platform === 'win32') {
|
|
193
|
+
console.log(`✅ Switched to ${envType} environment: ${envName}`);
|
|
194
|
+
console.log(`🚀 Starting new PowerShell session with ${envName} environment...`);
|
|
195
|
+
console.log(`Type "exit" to return to previous session\n`);
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
// 创建临时脚本文件
|
|
199
|
+
const os = require('os');
|
|
200
|
+
const fs = require('fs');
|
|
201
|
+
const tempScript = os.tmpdir() + '\\fnva_env_' + Date.now() + '.ps1';
|
|
202
|
+
|
|
203
|
+
// 写入环境设置脚本 + 启动交互式会话
|
|
204
|
+
const fullScript = script + '\n\n' +
|
|
205
|
+
'Write-Host "✨ Environment ready! You are now in fnva: ' + envName + '" -ForegroundColor Green\n' +
|
|
206
|
+
'Write-Host "Current Java version:" -ForegroundColor Yellow\n' +
|
|
207
|
+
'java --version\n' +
|
|
208
|
+
'Write-Host ""\n' +
|
|
209
|
+
'Write-Host "Type "exit" to return to previous session." -ForegroundColor Cyan\n' +
|
|
210
|
+
'Write-Host ""\n' +
|
|
211
|
+
'$Host.UI.RawUI.WindowTitle = "fnva: ' + envName + '"\n' +
|
|
212
|
+
'# Start interactive prompt\n' +
|
|
213
|
+
'while ($true) {\n' +
|
|
214
|
+
' try {\n' +
|
|
215
|
+
' $input = Read-Host "PS fnva:' + envName + '"\n' +
|
|
216
|
+
' if ($input -eq "exit") { break }\n' +
|
|
217
|
+
' if ($input.Trim() -ne "") {\n' +
|
|
218
|
+
' try {\n' +
|
|
219
|
+
' Invoke-Expression $input\n' +
|
|
220
|
+
' } catch {\n' +
|
|
221
|
+
' Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red\n' +
|
|
222
|
+
' }\n' +
|
|
223
|
+
' }\n' +
|
|
224
|
+
' } catch {\n' +
|
|
225
|
+
' break\n' +
|
|
226
|
+
' }\n' +
|
|
227
|
+
'}\n' +
|
|
228
|
+
'Write-Host "👋 Returning to original session..." -ForegroundColor Cyan\n';
|
|
98
229
|
|
|
99
|
-
|
|
230
|
+
fs.writeFileSync(tempScript, fullScript, 'utf8');
|
|
231
|
+
|
|
232
|
+
// 启动新的交互式 PowerShell 会话
|
|
233
|
+
const { spawn } = require('child_process');
|
|
234
|
+
const ps = spawn('powershell', ['-NoExit', '-ExecutionPolicy', 'Bypass', '-File', tempScript], {
|
|
235
|
+
stdio: 'inherit',
|
|
236
|
+
shell: false // 避免 shell 注入问题
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
ps.on('exit', (code) => {
|
|
240
|
+
// 清理临时文件
|
|
241
|
+
try {
|
|
242
|
+
fs.unlinkSync(tempScript);
|
|
243
|
+
} catch (e) {
|
|
244
|
+
// 忽略清理错误
|
|
245
|
+
}
|
|
246
|
+
console.log('👋 Returned to original session');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// 保持当前进程运行直到子进程结束
|
|
250
|
+
return;
|
|
251
|
+
|
|
252
|
+
} catch (error) {
|
|
253
|
+
console.error(`Failed to start PowerShell session: ${error.message}`);
|
|
254
|
+
console.log(`📝 Script was: ${script}`);
|
|
255
|
+
}
|
|
256
|
+
} else {
|
|
257
|
+
// Unix-like systems: 显示使用说明
|
|
258
|
+
console.log(`✅ Switched to ${envType} environment: ${envName}`);
|
|
259
|
+
console.log('');
|
|
260
|
+
console.log('💡 To apply this environment, run:');
|
|
261
|
+
console.log(` node bin/fnva.js ${args.join(' ')} | bash`);
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
// 如果不是环境脚本,直接输出
|
|
265
|
+
console.log(stdout);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// 如果有 stderr 输出,也显示出来
|
|
269
|
+
if (result.stderr) {
|
|
270
|
+
console.error(result.stderr);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
process.exit(0);
|
|
274
|
+
} else {
|
|
275
|
+
// 对于其他命令,使用原有的 stdio: 'inherit' 方式
|
|
276
|
+
const result = spawnSync(binaryPath, args, {
|
|
277
|
+
stdio: 'inherit',
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
if (result.error) {
|
|
281
|
+
console.error(`Failed to execute fnva: ${result.error.message}`);
|
|
282
|
+
process.exit(result.status ?? 1);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
process.exit(result.status ?? 0);
|
|
286
|
+
}
|
|
100
287
|
}
|
|
101
288
|
|
|
102
289
|
run();
|
package/bin/fnva.ps1
CHANGED
|
@@ -14,9 +14,17 @@ $platformDir = "$os-$arch"
|
|
|
14
14
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
15
15
|
$binaryPath = Join-Path $scriptDir ".." "platforms" $platformDir "fnva.exe"
|
|
16
16
|
|
|
17
|
+
# 如果分层结构不存在,尝试扁平结构
|
|
18
|
+
if (-not (Test-Path $binaryPath)) {
|
|
19
|
+
$binaryPath = Join-Path $scriptDir ".." "platforms" "fnva.exe"
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
# 检查二进制文件是否存在
|
|
18
23
|
if (-not (Test-Path $binaryPath)) {
|
|
19
|
-
Write-Host "错误:
|
|
24
|
+
Write-Host "错误: 未找到二进制文件" -ForegroundColor Red
|
|
25
|
+
Write-Host "尝试的路径: " -ForegroundColor Yellow
|
|
26
|
+
Write-Host " 1. $(Join-Path $scriptDir ".." "platforms" $platformDir "fnva.exe")" -ForegroundColor Yellow
|
|
27
|
+
Write-Host " 2. $(Join-Path $scriptDir ".." "platforms" "fnva.exe")" -ForegroundColor Yellow
|
|
20
28
|
Write-Host "请运行 'npm run build' 构建二进制文件" -ForegroundColor Yellow
|
|
21
29
|
exit 1
|
|
22
30
|
}
|
package/package.json
CHANGED
package/platforms/fnva
CHANGED
|
Binary file
|
package/platforms/fnva.exe
CHANGED
|
Binary file
|