fnva 0.0.10 → 0.0.11

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
@@ -28,6 +28,17 @@ yarn global add fnva
28
28
 
29
29
  # 使用 pnpm
30
30
  pnpm add -g fnva
31
+
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") {
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
38
+ } else {
39
+ & node bin\fnva.js $args
40
+ }
41
+ }
31
42
  ```
32
43
 
33
44
  ### 方式二:从 Releases 下载二进制文件
package/bin/fnva.js CHANGED
@@ -103,6 +103,43 @@ function hasSessionFlag(args) {
103
103
  return args.includes('--session');
104
104
  }
105
105
 
106
+ function hasApplyFlag(args) {
107
+ return args.includes('--apply');
108
+ }
109
+
110
+ function hasAutoExecuteFlag(args) {
111
+ return args.includes('--auto');
112
+ }
113
+
114
+ function removeAutoFlag(args) {
115
+ const index = args.indexOf('--auto');
116
+ if (index > -1) {
117
+ return args.slice(0, index).concat(args.slice(index + 1));
118
+ }
119
+ return args;
120
+ }
121
+
122
+ function createTempScriptFile(script, envType, envName) {
123
+ try {
124
+ const os = require('os');
125
+ const fs = require('fs');
126
+ const path = require('path');
127
+
128
+ const tempDir = os.tmpdir();
129
+ const scriptFile = path.join(tempDir, `fnva_${envType}_${envName}_${Date.now()}.ps1`);
130
+
131
+ fs.writeFileSync(scriptFile, script, 'utf8');
132
+
133
+ console.log('');
134
+ console.log('💡 环境已切换到当前进程。要在新的 PowerShell 窗口中使用此环境,运行:');
135
+ console.log(` ${scriptFile}`);
136
+ console.log(' 或者: fnva', envType, 'use', envName, '--auto');
137
+
138
+ } catch (error) {
139
+ console.warn('⚠️ 无法创建临时脚本文件:', error.message);
140
+ }
141
+ }
142
+
106
143
  function parseEnvironmentScript(scriptContent) {
107
144
  if (!scriptContent || scriptContent.trim() === '') {
108
145
  return {};
@@ -120,10 +157,25 @@ function parseEnvironmentScript(scriptContent) {
120
157
  const trimmedLine = line.trim();
121
158
 
122
159
  // 解析 PowerShell 环境变量设置
123
- if (trimmedLine.startsWith('$env:')) {
124
- const match = trimmedLine.match(/\$env:(\w+)\s*=\s*"([^"]*)"/);
160
+ if (trimmedLine.includes('$env:')) {
161
+ // 匹配 $env:VARNAME = "value" 格式
162
+ let match = trimmedLine.match(/\$env:(\w+)\s*=\s*"([^"]*)"/);
125
163
  if (match) {
126
164
  envVars[match[1]] = match[2];
165
+ continue;
166
+ }
167
+
168
+ // 匹配 $env:VARNAME = 'value' 格式
169
+ match = trimmedLine.match(/\$env:(\w+)\s*=\s*'([^']*)'/);
170
+ if (match) {
171
+ envVars[match[1]] = match[2];
172
+ continue;
173
+ }
174
+
175
+ // 匹配 $env:VARNAME = value 格式(不带引号)
176
+ match = trimmedLine.match(/\$env:(\w+)\s*=\s*([^;]+)/);
177
+ if (match) {
178
+ envVars[match[1]] = match[2].trim().replace(/['"]/g, '');
127
179
  }
128
180
  }
129
181
 
@@ -134,12 +186,6 @@ function parseEnvironmentScript(scriptContent) {
134
186
  envVars[match[1]] = match[2];
135
187
  }
136
188
  }
137
-
138
- // 解析不带引号的环境变量设置
139
- const unquotedMatch = trimmedLine.match(/\$env:(\w+)\s*=\s*([^;]+)/);
140
- if (unquotedMatch) {
141
- envVars[unquotedMatch[1]] = unquotedMatch[2].trim();
142
- }
143
189
  }
144
190
 
145
191
  return envVars;
@@ -167,6 +213,65 @@ function displaySuccessMessage(envType, envName, envVars) {
167
213
  }
168
214
  }
169
215
 
216
+ function generateSimpleScript(envVars, envType, envName) {
217
+ const lines = [];
218
+
219
+ if (process.platform === 'win32') {
220
+ // Windows PowerShell
221
+ lines.push(`Write-Host "Switched to ${envType} environment: ${envName}" -ForegroundColor Green`);
222
+
223
+ if (envVars.JAVA_HOME) {
224
+ lines.push(`$env:JAVA_HOME = "${envVars.JAVA_HOME}"`);
225
+ // 对于 PATH,我们需要智能处理:移除旧的 Java 路径,添加新的
226
+ lines.push(`# Remove existing Java paths from PATH`);
227
+ lines.push(`$pathParts = $env:PATH -split ';'`);
228
+ lines.push(`$cleanPath = @()`);
229
+ lines.push(`foreach ($part in $pathParts) {`);
230
+ lines.push(` if ($part -notmatch 'java' -and $part -notmatch 'jdk') {`);
231
+ lines.push(` $cleanPath += $part`);
232
+ lines.push(` }`);
233
+ lines.push(`}`);
234
+ lines.push(`$env:PATH = "${envVars.JAVA_HOME}\\bin;" + ($cleanPath -join ';')`);
235
+ lines.push(`Write-Host "JAVA_HOME: $env:JAVA_HOME" -ForegroundColor Yellow`);
236
+ }
237
+
238
+ if (envVars.ANTHROPIC_AUTH_TOKEN) {
239
+ lines.push(`$env:ANTHROPIC_AUTH_TOKEN = "${envVars.ANTHROPIC_AUTH_TOKEN}"`);
240
+ lines.push(`Write-Host "ANTHROPIC_AUTH_TOKEN: [已设置]" -ForegroundColor Yellow`);
241
+ }
242
+
243
+ if (envVars.OPENAI_API_KEY) {
244
+ lines.push(`$env:OPENAI_API_KEY = "${envVars.OPENAI_API_KEY}"`);
245
+ lines.push(`Write-Host "OPENAI_API_KEY: [已设置]" -ForegroundColor Yellow`);
246
+ }
247
+ } else {
248
+ // Unix-like systems
249
+ lines.push(`echo "Switched to ${envType} environment: ${envName}"`);
250
+
251
+ if (envVars.JAVA_HOME) {
252
+ lines.push(`export JAVA_HOME="${envVars.JAVA_HOME}"`);
253
+ // 对于 PATH,我们也需要智能处理
254
+ lines.push(`# Remove existing Java paths from PATH`);
255
+ lines.push(`echo $PATH | tr ':' '\\n' | grep -v java | grep -v jdk | tr '\\n' ':' | sed 's/:$//' > /tmp/clean_path`);
256
+ lines.push(`export PATH="${envVars.JAVA_HOME}/bin:$(cat /tmp/clean_path)"`);
257
+ lines.push(`rm -f /tmp/clean_path`);
258
+ lines.push(`echo "JAVA_HOME: $JAVA_HOME"`);
259
+ }
260
+
261
+ if (envVars.ANTHROPIC_AUTH_TOKEN) {
262
+ lines.push(`export ANTHROPIC_AUTH_TOKEN="${envVars.ANTHROPIC_AUTH_TOKEN}"`);
263
+ lines.push(`echo "ANTHROPIC_AUTH_TOKEN: [已设置]"`);
264
+ }
265
+
266
+ if (envVars.OPENAI_API_KEY) {
267
+ lines.push(`export OPENAI_API_KEY="${envVars.OPENAI_API_KEY}"`);
268
+ lines.push(`echo "OPENAI_API_KEY: [已设置]"`);
269
+ }
270
+ }
271
+
272
+ return lines.join('\n');
273
+ }
274
+
170
275
  function run() {
171
276
  const binaryPath = buildBinaryPath();
172
277
 
@@ -180,7 +285,13 @@ function run() {
180
285
  process.exit(1);
181
286
  }
182
287
 
183
- const args = process.argv.slice(2);
288
+ let args = process.argv.slice(2);
289
+
290
+ // 如果设置了 FNVA_AUTO_EXECUTE,则为环境切换命令启用自动执行
291
+ if (process.env.FNVA_AUTO_EXECUTE === '1' && isEnvironmentSwitchCommand(args) && !hasSessionFlag(args)) {
292
+ // 添加 --auto 标志来启用自动执行
293
+ args = args.concat('--auto');
294
+ }
184
295
  const isSwitchCommand = isEnvironmentSwitchCommand(args);
185
296
 
186
297
  if (isSwitchCommand) {
@@ -248,13 +359,45 @@ function run() {
248
359
  console.log(`📝 Script was: ${script}`);
249
360
  }
250
361
  } else {
251
- console.log(`✅ Switched to ${envType} environment: ${envName}`);
252
- if (process.stdout.isTTY) {
253
- console.log('');
254
- console.log('💡 在当前会话应用环境:');
255
- console.log(` fnva ${envType} use ${envName} --shell powershell | Invoke-Expression`);
362
+ // 检查是否使用了 --apply 参数
363
+ if (hasApplyFlag(args)) {
364
+ // 直接应用环境变量到当前进程
365
+ const envVars = parseEnvironmentScript(script);
366
+ applyEnvironmentVariables(envVars);
367
+ displaySuccessMessage(envType, envName, envVars);
256
368
  } else {
257
- process.stdout.write(script);
369
+ // 在 Windows 中,智能处理环境设置
370
+ const envVars = parseEnvironmentScript(script);
371
+ const simpleScript = generateSimpleScript(envVars, envType, envName);
372
+
373
+ // 尝试自动执行(如果可能)
374
+ if (process.env.FNVA_AUTO_EXECUTE === '1') {
375
+ const os = require('os');
376
+ const fs = require('fs');
377
+ const path = require('path');
378
+ const { spawn } = require('child_process');
379
+
380
+ try {
381
+ const tempFile = path.join(os.tmpdir(), `fnva_auto_${Date.now()}.ps1`);
382
+ fs.writeFileSync(tempFile, simpleScript, 'utf8');
383
+
384
+ // 使用 PowerShell 执行脚本
385
+ spawn('powershell', ['-ExecutionPolicy', 'Bypass', '-File', tempFile], {
386
+ stdio: 'inherit',
387
+ shell: false
388
+ }).on('exit', () => {
389
+ try { fs.unlinkSync(tempFile); } catch (_) {}
390
+ });
391
+
392
+ console.log('✅ 环境已自动切换');
393
+ return;
394
+ } catch (error) {
395
+ console.warn('⚠️ 自动执行失败,回退到脚本输出');
396
+ }
397
+ }
398
+
399
+ // 默认输出脚本
400
+ process.stdout.write(simpleScript);
258
401
  }
259
402
  }
260
403
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fnva",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "跨平台环境切换工具,支持 Java 和 LLM 环境配置",
5
5
  "author": "protagonistss",
6
6
  "license": "MIT",
package/platforms/fnva CHANGED
Binary file
Binary file
Binary file