Skip to content

Commit 0ea7370

Browse files
c2ndevpoiana
authored andcommitted
fix(installers/windows): launcher captures daemon crash output
Signed-off-by: c2ndev <cannarella.dev@gmail.com>
1 parent 0888164 commit 0ea7370

1 file changed

Lines changed: 43 additions & 5 deletions

File tree

installers/windows/prempti-launcher.ps1

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
66
.DESCRIPTION
77
Hides the console window (via the PowerShell host invocation) and
8-
invokes `premptictl daemon`. The supervisor owns the
9-
Falco process, log files, rotation, and Claude Code hook lifecycle.
10-
Runs in the foreground so the supervisor's stop signals reach it.
8+
invokes `premptictl daemon`. The supervisor owns the Falco process,
9+
log files, rotation, and Claude Code hook lifecycle. Runs in the
10+
foreground so the supervisor's stop signals reach it. Captures the
11+
supervisor's own stderr to log/supervisor.err so an early crash
12+
(before Falco's logs are open) leaves a breadcrumb for the user.
1113
#>
1214
param(
1315
[string]$Prefix = (Join-Path $env:LOCALAPPDATA 'prempti')
@@ -17,5 +19,41 @@ Set-StrictMode -Version Latest
1719
$ErrorActionPreference = 'Continue'
1820

1921
$Ctl = Join-Path $Prefix 'bin\premptictl.exe'
20-
& $Ctl daemon --prefix $Prefix
21-
exit $LASTEXITCODE
22+
$LogDir = Join-Path $Prefix 'log'
23+
if (-not (Test-Path $LogDir)) {
24+
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
25+
}
26+
$SupervisorErr = Join-Path $LogDir 'supervisor.err'
27+
28+
# Truncate per-run; only the latest launch's supervisor stderr is useful for
29+
# diagnosing a failed startup. Use UTF-8 without BOM so Add-Content / external
30+
# tools don't have to skip a BOM.
31+
[IO.File]::WriteAllText($SupervisorErr, '', [System.Text.UTF8Encoding]::new($false))
32+
33+
$psi = New-Object System.Diagnostics.ProcessStartInfo
34+
$psi.FileName = $Ctl
35+
$psi.Arguments = "daemon --prefix `"$Prefix`""
36+
$psi.UseShellExecute = $false
37+
$psi.RedirectStandardError = $true
38+
$psi.CreateNoWindow = $true
39+
$proc = [System.Diagnostics.Process]::Start($psi)
40+
41+
# Drain stderr asynchronously to avoid a 4 KB OS pipe-buffer deadlock if the
42+
# supervisor logs steadily. Each line is appended to supervisor.err.
43+
$drain = Register-ObjectEvent -InputObject $proc -EventName ErrorDataReceived -Action {
44+
if ($EventArgs.Data) {
45+
[IO.File]::AppendAllText($Event.MessageData, $EventArgs.Data + "`r`n",
46+
[System.Text.UTF8Encoding]::new($false))
47+
}
48+
} -MessageData $SupervisorErr
49+
$proc.BeginErrorReadLine()
50+
51+
$proc.WaitForExit()
52+
# Per MSDN, calling WaitForExit() a second time after the first returns ensures
53+
# all async events fire before we tear down the registration.
54+
$proc.WaitForExit()
55+
56+
if ($drain) {
57+
Unregister-Event -SourceIdentifier $drain.Name -ErrorAction SilentlyContinue
58+
}
59+
exit $proc.ExitCode

0 commit comments

Comments
 (0)