From e10d2e9a31cd3a1dce2cb505d1c2ed7d0f8fcb4f Mon Sep 17 00:00:00 2001 From: Hrt-Htk Date: Thu, 16 Jul 2026 08:51:26 +0200 Subject: [PATCH] feat(watchdog): auto-start watchdogs minimized at login (#11) Add create-startup-shortcuts.ps1 to install/remove minimized Startup-folder shortcuts for both watchdogs. Runs at logon in the interactive session, non-elevated (fires on auto-login, no stored credentials needed, and avoids the elevated-orphan-worker issue from /RL HIGHEST tasks). Set stable console titles (llama-chat-watchdog, llama-embed-supervisor) so the daily restart scripts find each window reliably; titles are chosen so the chat restart no longer accidentally matches the embed watchdog window. Relaunch minimized in restart-watchdog.ps1 / restart-watchdog-embed.ps1 so the windows stay minimized after the midnight restart. Minimized (not hidden) preserves the window handle/title that the WM_CLOSE shutdown cascade targets. Co-Authored-By: Claude Opus 4.8 --- create-startup-shortcuts.ps1 | 67 ++++++++++++++++++++++++++++++++++++ restart-watchdog-embed.ps1 | 4 +-- restart-watchdog.ps1 | 4 +-- watchdog-embed.ps1 | 6 ++++ watchdog.ps1 | 6 ++++ 5 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 create-startup-shortcuts.ps1 diff --git a/create-startup-shortcuts.ps1 b/create-startup-shortcuts.ps1 new file mode 100644 index 0000000..3562c79 --- /dev/null +++ b/create-startup-shortcuts.ps1 @@ -0,0 +1,67 @@ +<# +Installs (or removes) startup shortcuts so both watchdogs launch automatically, +minimized to the taskbar, when you log in. + +- Runs at LOGON in your interactive desktop session (fires on Windows auto-login, + so no username/password is required — unlike a "run whether logged on or not" + boot task, which would need stored credentials). +- Non-elevated, matching how the watchdogs are normally run by hand. This also + avoids the elevated-orphan-worker problem seen with /RL HIGHEST tasks. +- Minimized window (not hidden) so the daily restart scripts can still find the + console by title and send WM_CLOSE for a clean llama-server shutdown. + +Usage: + .\create-startup-shortcuts.ps1 # install + .\create-startup-shortcuts.ps1 -Remove # uninstall +#> +param([switch]$Remove) + +$ErrorActionPreference = "Stop" +$scriptDir = Split-Path $PSCommandPath -Parent +$startup = [Environment]::GetFolderPath('Startup') + +# WindowStyle for .lnk: 1 = Normal, 3 = Maximized, 7 = Minimized +$MINIMIZED = 7 + +$shortcuts = @( + @{ Name = "LLAMA Chat Watchdog"; Script = "watchdog.ps1" } + @{ Name = "LLAMA Embed Watchdog"; Script = "watchdog-embed.ps1" } +) + +if ($Remove) { + foreach ($s in $shortcuts) { + $lnk = Join-Path $startup "$($s.Name).lnk" + if (Test-Path $lnk) { + Remove-Item $lnk -Force + Write-Host "[OK] Removed $lnk" -ForegroundColor Green + } else { + Write-Host "[--] Not present: $lnk" -ForegroundColor DarkGray + } + } + return +} + +$wsh = New-Object -ComObject WScript.Shell + +foreach ($s in $shortcuts) { + $target = Join-Path $scriptDir $s.Script + if (-not (Test-Path $target)) { throw "Watchdog script not found: $target" } + + $lnkPath = Join-Path $startup "$($s.Name).lnk" + $lnk = $wsh.CreateShortcut($lnkPath) + $lnk.TargetPath = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" + $lnk.Arguments = "-NoProfile -ExecutionPolicy Bypass -NoExit -File `"$target`"" + $lnk.WorkingDirectory = $scriptDir + $lnk.WindowStyle = $MINIMIZED + $lnk.Description = "Auto-start $($s.Script) minimized at logon" + $lnk.Save() + Write-Host "[OK] Installed $lnkPath (minimized, launches $($s.Script))" -ForegroundColor Green +} + +Write-Host "" +Write-Host "Startup folder: $startup" +Write-Host "They will launch minimized on your next login. To start them now:" +Write-Host " Start-Process powershell -WindowStyle Minimized -ArgumentList '-NoProfile','-NoExit','-File','$(Join-Path $scriptDir "watchdog.ps1")'" +Write-Host " Start-Process powershell -WindowStyle Minimized -ArgumentList '-NoProfile','-NoExit','-File','$(Join-Path $scriptDir "watchdog-embed.ps1")'" +Write-Host "" +Write-Host "To remove: .\create-startup-shortcuts.ps1 -Remove" diff --git a/restart-watchdog-embed.ps1 b/restart-watchdog-embed.ps1 index 214a26d..6c89fd4 100644 --- a/restart-watchdog-embed.ps1 +++ b/restart-watchdog-embed.ps1 @@ -71,9 +71,9 @@ if (-not $found) { # --- Brief pause before restart to let ports fully release --- Start-Sleep -Seconds 3 -# --- Launch fresh embed watchdog in a visible console --- +# --- Launch fresh embed watchdog in a minimized console --- Log "Starting fresh embed watchdog" -Start-Process powershell -WindowStyle Normal ` +Start-Process powershell -WindowStyle Minimized ` -ArgumentList "-NoExit", "-NoProfile", "-File", "`"$watchdog`"" ` -WorkingDirectory $scriptDir diff --git a/restart-watchdog.ps1 b/restart-watchdog.ps1 index dfc7d11..456a1ec 100644 --- a/restart-watchdog.ps1 +++ b/restart-watchdog.ps1 @@ -76,9 +76,9 @@ if (-not $found) { # --- Brief pause before restart to let ports fully release --- Start-Sleep -Seconds 3 -# --- Launch fresh watchdog in a visible console --- +# --- Launch fresh watchdog in a minimized console --- Log "Starting fresh watchdog" -Start-Process powershell -WindowStyle Normal ` +Start-Process powershell -WindowStyle Minimized ` -ArgumentList "-NoExit", "-NoProfile", "-File", "`"$watchdog`"" ` -WorkingDirectory $scriptDir diff --git a/watchdog-embed.ps1 b/watchdog-embed.ps1 index 4e9e8e8..462fa4a 100644 --- a/watchdog-embed.ps1 +++ b/watchdog-embed.ps1 @@ -2,6 +2,12 @@ # Usage: .\watchdog-embed.ps1 [extra args forwarded to embed_proxy.py] $ErrorActionPreference = "Stop" + +# Stable console title so the daily restart scripts can find this window by +# title (matches *embed*, and deliberately contains no "watchdog" so the chat +# restart never catches this window). Also survives minimized launches. +$host.UI.RawUI.WindowTitle = "llama-embed-supervisor" + $scriptDir = Split-Path $PSCommandPath -Parent $python = Join-Path $scriptDir ".venv\Scripts\python.exe" $proxy = Join-Path $scriptDir "embed_proxy.py" diff --git a/watchdog.ps1 b/watchdog.ps1 index 7f6d368..4cf1926 100644 --- a/watchdog.ps1 +++ b/watchdog.ps1 @@ -8,6 +8,12 @@ # --model and --ctx-size only set the fallback when a client omits the model. $ErrorActionPreference = "Stop" + +# Stable console title so the daily restart scripts can find this window by +# title (matches *watchdog*, and deliberately contains no "embed" so the chat +# restart never catches the embed watchdog). Also survives minimized launches. +$host.UI.RawUI.WindowTitle = "llama-chat-watchdog" + $scriptDir = Split-Path $PSCommandPath -Parent $python = Join-Path $scriptDir ".venv\Scripts\python.exe" $proxy = Join-Path $scriptDir "proxy.py"