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#>
1214param (
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