@myassis/gateway 1.0.67 → 1.0.69

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.
@@ -94,7 +94,9 @@ function getStoredPid() {
94
94
  try {
95
95
  if (!fs_1.default.existsSync(GATEWAY_PID_FILE))
96
96
  return null;
97
- const pid = parseInt(fs_1.default.readFileSync(GATEWAY_PID_FILE, 'utf8').trim(), 10);
97
+ // 去除 PowerShell Out-File -Encoding UTF8 写入的 BOM(\uFEFF),否则 parseInt 会得到 NaN
98
+ const raw = fs_1.default.readFileSync(GATEWAY_PID_FILE, 'utf8').replace(/^\uFEFF/, '').trim();
99
+ const pid = parseInt(raw, 10);
98
100
  return isNaN(pid) ? null : pid;
99
101
  }
100
102
  catch {
@@ -149,7 +151,7 @@ async function stopGatewayProcess() {
149
151
  // 同时杀掉守护进程(防止它重新拉起 gateway)
150
152
  if (process.platform === 'win32') {
151
153
  try {
152
- const daemonPidStr = fs_1.default.readFileSync(GATEWAY_DAEMON_PID_FILE, 'utf8').trim();
154
+ const daemonPidStr = fs_1.default.readFileSync(GATEWAY_DAEMON_PID_FILE, 'utf8').replace(/^\uFEFF/, '').trim();
153
155
  const daemonPid = parseInt(daemonPidStr, 10);
154
156
  if (daemonPid && !isNaN(daemonPid)) {
155
157
  try {
@@ -197,18 +199,18 @@ function writeGatewayLauncherScript(exePath, scriptPath, workDir) {
197
199
  '',
198
200
  'function Start-Gateway {',
199
201
  " Write-Log '启动 Gateway 进程...'",
200
- ' $psi = New-Object System.Diagnostics.ProcessStartInfo',
201
- ' $psi.FileName = $exe',
202
- ' $psi.WorkingDirectory = $workDir',
203
- ' $psi.UseShellExecute = $false',
204
- ' $psi.RedirectStandardOutput = $true',
205
- ' $psi.RedirectStandardError = $true',
206
- ' $psi.CreateNoWindow = $true',
207
- ' $proc = [System.Diagnostics.Process]::Start($psi)',
208
- ' if ($proc) {',
209
- ' $proc.Id.ToString() | Out-File -FilePath $pidFile -Encoding UTF8',
210
- " Write-Log \"Gateway 已启动,PID=$($proc.Id)\"",
211
- ' return $proc',
202
+ ' # Start-Process 启动,不重定向 stdout/stderr,避免:',
203
+ ' # 1) 管道缓冲区填满后 gateway 卡死(4KB 缓冲区无人读取)',
204
+ ' # 2) 父 PS 句柄继承导致 gateway 写 stdout 崩溃',
205
+ ' try {',
206
+ ' $proc = Start-Process -FilePath $exe -WorkingDirectory $workDir -WindowStyle Hidden -PassThru -ErrorAction Stop',
207
+ ' if ($proc -and $proc.Id) {',
208
+ ' $proc.Id.ToString() | Out-File -FilePath $pidFile -Encoding UTF8',
209
+ " Write-Log \"Gateway 已启动,PID=$($proc.Id)\"",
210
+ ' return $proc',
211
+ ' }',
212
+ ' } catch {',
213
+ " Write-Log \"Gateway 启动失败: $($_.Exception.Message)\"",
212
214
  ' }',
213
215
  " Write-Log 'Gateway 启动失败'",
214
216
  ' return $null',
@@ -224,10 +226,13 @@ function writeGatewayLauncherScript(exePath, scriptPath, workDir) {
224
226
  '# 守护循环:监控进程状态,异常退出则自动重启',
225
227
  'while ($true) {',
226
228
  ' try {',
227
- ' # 等待进程退出(每 5 秒检查一次,防止卡死)',
228
- ' $exited = $proc.WaitForExit(5000)',
229
- ' if ($exited) {',
230
- ' $exitCode = $proc.ExitCode',
229
+ ' # 5 秒检查一次进程是否仍在运行',
230
+ ' Start-Sleep -Seconds 5',
231
+ '',
232
+ ' # 进程已退出',
233
+ ' if ($proc.HasExited) {',
234
+ ' $exitCode = -1',
235
+ ' try { $exitCode = $proc.ExitCode } catch { }',
231
236
  " Write-Log \"Gateway 进程已退出,退出码=$exitCode\"",
232
237
  '',
233
238
  ' # 检查是否是主动停止',
@@ -562,19 +567,20 @@ async function ensureAutoStartHealthy() {
562
567
  const lower = currentValue.toLowerCase();
563
568
  const hasPowershell = lower.includes('powershell.exe');
564
569
  const pointsToNewPath = lower.includes(GATEWAY_LAUNCHER_FILE.toLowerCase());
565
- // 脚本内容健康:不能含 RedirectStandardOutput/WaitForExit(旧版本管道阻塞 bug),
566
- // 也不能是 UseShellExecute=$false(会继承父 PS 句柄,PS 退出后 gateway 写 stdout 崩溃)
570
+ // 脚本内容健康:不能含 RedirectStandardOutput(旧版管道阻塞 bug),
571
+ // 也不能是 UseShellExecute=$false(会继承父 PS 句柄,PS 退出后 gateway 写 stdout 崩溃),
572
+ // 并且必须含 Start-Process(新版守护脚本的启动方式)
567
573
  let scriptHealthy = false;
568
574
  try {
569
575
  if (fs_1.default.existsSync(GATEWAY_LAUNCHER_FILE)) {
570
576
  const scriptContent = fs_1.default.readFileSync(GATEWAY_LAUNCHER_FILE, 'utf8');
571
577
  // 老版包含以下任一特征就重写:
572
- // 1) RedirectStandardOutput → 管道阻塞旧 bug
573
- // 2) WaitForExitPS 陆跑浪费内存
574
- // 3) UseShellExecute = $false → 句柄继承导致进程崩溃(本次修复)
578
+ // 1) RedirectStandardOutput → 管道阻塞旧 bug(无人读管道导致 gateway 卡死)
579
+ // 2) UseShellExecute = $false 句柄继承导致进程崩溃
580
+ // 新版必须用 Start-Process 启动(不含则说明是旧脚本)
575
581
  scriptHealthy = !scriptContent.includes('RedirectStandardOutput')
576
- && !scriptContent.includes('WaitForExit')
577
- && !scriptContent.includes('UseShellExecute = $false');
582
+ && !scriptContent.includes('UseShellExecute = $false')
583
+ && scriptContent.includes('Start-Process');
578
584
  }
579
585
  }
580
586
  catch { /* ignore */ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myassis/gateway",
3
- "version": "1.0.67",
3
+ "version": "1.0.69",
4
4
  "description": "我的助手 Gateway Service - 本地 AI 网关服务,支持认证、WebSocket 实时通信和任务调度",
5
5
  "main": "dist/index.js",
6
6
  "bin": {