fix: 修复 Windows 安装后无法启动 —— PowerShell 写入的 JSON 带 UTF-8 BOM

真机报错:启动失败: Unexpected token '', "{"a"... is not valid JSON
根因:Windows PowerShell 5.1 的 Set-Content -Encoding UTF8 会写入 BOM(U+FEFF),
      Node 侧 JSON.parse 拒绝解析带 BOM 的文本。

双管齐下修复:
1. 写端 install.ps1:改用 [System.IO.File]::WriteAllText + UTF8Encoding($false)
   写出无 BOM 的 UTF-8
2. 读端容错(兼容已被写坏的配置):
   - apps/agent/src/config.ts:读配置时剥离开头 BOM
   - packages/client/src/config.ts:同上

验证:构造带 BOM 的 agent.json(ef bb bf 开头),agent 可正常启动;
单元 26/26、E2E 21/21 全绿
This commit is contained in:
jkooe committed 2026-09-27 19:32:53 +08:00
1 parent b350a41803
commit 3316f08c92
3 files changed
+12 -4

No files matched your search

+4 -1
View File
@@ -92,7 +92,10 @@ export function defaultAgentConfig(): AgentConfig {
export function loadAgentConfig(): { config: AgentConfig; isNew: boolean } {
const p = agentConfigPath();
if (existsSync(p)) {
const cfg = JSON.parse(readFileSync(p, 'utf8')) as AgentConfig;
// 剥离 UTF-8 BOM:Windows 上由 PowerShell 写出的 JSON 可能带 BOM,
// 直接 JSON.parse 会报 "Unexpected token ''"
const text = readFileSync(p, 'utf8').replace(/^\uFEFF/, '');
const cfg = JSON.parse(text) as AgentConfig;
const envKey = process.env['NODEAGENT_KEY'];
if (envKey) cfg.key = envKey;
return { config: cfg, isNew: false };
+3 -1
View File
@@ -85,7 +85,9 @@ function migrate(raw: Record<string, unknown>): ClientConfig {
export function loadConfig(): ClientConfig | null {
const p = configPath();
if (!existsSync(p)) return null;
const raw = JSON.parse(readFileSync(p, 'utf8')) as Record<string, unknown>;
// 剥离 UTF-8 BOM(跨平台健壮:某些编辑器 / PowerShell 会写入 BOM)
const text = readFileSync(p, 'utf8').replace(/^\uFEFF/, '');
const raw = JSON.parse(text) as Record<string, unknown>;
const cfg = migrate(raw);
const envKey = process.env['NODEAGENT_KEY'];
const cur = cfg.nodes[cfg.current];
+5 -2
View File
@@ -105,7 +105,7 @@ if (-not $Key) {
Write-Ok "Generated a new pre-shared key"
}
@{
$cfgJson = @{
node_id = $NodeId
host = "0.0.0.0"
port = $Port
@@ -114,7 +114,10 @@ if (-not $Key) {
log_level = "info"
allow_input = [bool]$AllowInput
auth_mode = "psk"
} | ConvertTo-Json | Set-Content -Path $cfgPath -Encoding UTF8
} | ConvertTo-Json
# 必须写「无 BOM」的 UTF-8:Windows PowerShell 5.1 的 `Set-Content -Encoding UTF8`
# 会写入 BOM(U+FEFF),导致 Node 侧 JSON.parse 报 "Unexpected token ''"
[System.IO.File]::WriteAllText($cfgPath, $cfgJson, (New-Object System.Text.UTF8Encoding($false)))
Write-Ok "Config written: $cfgPath"
# 5. Firewall (inbound, agent listens)