From c2a6219d926a292ec7bcd29177e252ff307ce3de Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:32:36 +0800 Subject: [PATCH 01/12] refactor: consolidate WSL native notifications --- config/scripts/wsl-notify.ps1 | 110 ++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 config/scripts/wsl-notify.ps1 diff --git a/config/scripts/wsl-notify.ps1 b/config/scripts/wsl-notify.ps1 new file mode 100644 index 00000000..3be5eeb6 --- /dev/null +++ b/config/scripts/wsl-notify.ps1 @@ -0,0 +1,110 @@ +param( + [Parameter(Mandatory = $true)][string] $Title, + [Parameter(Mandatory = $true)][string] $Message +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +# Exit codes consumed by wsl-notify.plugin.zsh: +# 0 toast displayed +# 10 Windows Terminal is focused; notification intentionally suppressed +# 11 foreground state could not be determined; fail closed +# 20 native toast delivery failed; the shell may fall back to BEL +$ExitToastShown = 0 +$ExitFocused = 10 +$ExitFocusUnknown = 11 +$ExitDeliveryFailed = 20 + +function Get-ForegroundProcessName { + try { + Add-Type -TypeDefinition @" +using System; +using System.Runtime.InteropServices; + +public static class ForegroundWindow { + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll", SetLastError = true)] + public static extern uint GetWindowThreadProcessId(IntPtr window, out uint processId); +} +"@ + + $window = [ForegroundWindow]::GetForegroundWindow() + if ($window -eq [IntPtr]::Zero) { + return $null + } + + $foregroundProcessId = [uint32]0 + $threadId = [ForegroundWindow]::GetWindowThreadProcessId($window, [ref] $foregroundProcessId) + if ($threadId -eq 0 -or $foregroundProcessId -eq 0) { + return $null + } + + return (Get-Process -Id $foregroundProcessId -ErrorAction Stop).ProcessName + } + catch { + return $null + } +} + +function Get-NotificationAppId { + $startApps = @(Get-StartApps) + + foreach ($candidate in @( + 'Microsoft.WindowsTerminal_8wekyb3d8bbwe!App', + 'Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe!App' + )) { + if ($startApps.AppID -contains $candidate) { + return $candidate + } + } + + $appId = $startApps | + Where-Object { $_.AppID -match '^Microsoft\.WindowsTerminal.*!App$' } | + Select-Object -First 1 -ExpandProperty AppID + + if (-not [string]::IsNullOrWhiteSpace($appId)) { + return $appId + } + + return $startApps | + Where-Object { $_.AppID -match 'PowerShell' } | + Select-Object -First 1 -ExpandProperty AppID +} + +$foregroundProcess = Get-ForegroundProcessName +if ([string]::IsNullOrWhiteSpace($foregroundProcess)) { + exit $ExitFocusUnknown +} + +if ($foregroundProcess -like 'WindowsTerminal*') { + exit $ExitFocused +} + +try { + Add-Type -AssemblyName System.Runtime.WindowsRuntime + $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] + $null = [Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] + $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] + + $appId = Get-NotificationAppId + if ([string]::IsNullOrWhiteSpace($appId)) { + throw 'No Start-menu AUMID suitable for WSL toast notifications was found.' + } + + $document = [Windows.Data.Xml.Dom.XmlDocument]::new() + $document.LoadXml('') + $textNodes = $document.GetElementsByTagName('text') + [void] $textNodes.Item(0).AppendChild($document.CreateTextNode($Title)) + [void] $textNodes.Item(1).AppendChild($document.CreateTextNode($Message)) + + $toast = [Windows.UI.Notifications.ToastNotification]::new($document) + [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($appId).Show($toast) + exit $ExitToastShown +} +catch { + [Console]::Error.WriteLine("WSL notification failed: $($_.Exception.Message)") + exit $ExitDeliveryFailed +} From 22189c4a074c1ff6b6c58eb3a6b9154a7bf01ccb Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:32:50 +0800 Subject: [PATCH 02/12] refactor: route WSL notifications through one helper --- .../sheldon/plugins/wsl-notify.plugin.zsh | 79 ++++++++----------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/home/.config/sheldon/plugins/wsl-notify.plugin.zsh b/home/.config/sheldon/plugins/wsl-notify.plugin.zsh index 81f7599b..adee4a3c 100644 --- a/home/.config/sheldon/plugins/wsl-notify.plugin.zsh +++ b/home/.config/sheldon/plugins/wsl-notify.plugin.zsh @@ -12,41 +12,23 @@ if [[ ${TERM_PROGRAM:-} == ghostty ]]; then return fi -# Windows Terminal is outside WSL's X/Wayland tree. Query Win32 directly so -# bgnotify only fires when Windows Terminal is not the foreground application. if [[ -n ${WT_SESSION:-} ]]; then - if [[ -n ${commands[powershell.exe]:-} ]]; then - function bgnotify_appid { - local process_name - process_name=$( - powershell.exe -NoLogo -NoProfile -NonInteractive -Command ' -Add-Type -TypeDefinition @" -using System; -using System.Runtime.InteropServices; -public static class ForegroundWindow { - [DllImport("user32.dll")] - public static extern IntPtr GetForegroundWindow(); - [DllImport("user32.dll")] - public static extern uint GetWindowThreadProcessId(IntPtr window, out uint processId); -} -"@ -$window = [ForegroundWindow]::GetForegroundWindow() -$foregroundPid = [uint32]0 -[void][ForegroundWindow]::GetWindowThreadProcessId($window, [ref]$foregroundPid) -(Get-Process -Id $foregroundPid).ProcessName -' 2>/dev/null | tr -d '\r\n' - ) - print -r -- "${process_name:-$EPOCHSECONDS}" - } - bgnotify_termid=WindowsTerminal - else - # Without the Win32 foreground probe we cannot guarantee background-only - # notifications, so fail closed instead of notifying while focused. + if [[ -z ${commands[powershell.exe]:-} || -z ${commands[wslpath]:-} ]]; then + # Without the Windows-native helper path we cannot reliably distinguish a + # focused terminal from a background one, so fail closed. autoload -Uz add-zsh-hook add-zsh-hook -d preexec bgnotify_begin add-zsh-hook -d precmd bgnotify_end return fi + + # Keep upstream bgnotify's timing and command formatting, but defer the + # Windows foreground check to wsl-notify.ps1. These fixed, unequal IDs make + # bgnotify_end dispatch without spawning a separate PowerShell probe. + function bgnotify_appid { + print -r -- '__wsl_notify_dispatch__' + } + bgnotify_termid='__wsl_notify_terminal_foreground__' fi function bgnotify { @@ -55,23 +37,32 @@ function bgnotify { local icon="$3" if [[ -n ${WT_SESSION:-} ]]; then - # bgnotify_end already verified that Windows Terminal is in the background. - # Send a real Windows toast; its default audio replaces the terminal BEL. - local toast_script="${MISE_CONFIG_DIR:-$HOME/.config/mise}/scripts/wsl-toast.ps1" - local windows_toast_script + local notify_script="${MISE_CONFIG_DIR:-$HOME/.config/mise}/scripts/wsl-notify.ps1" + local windows_notify_script + local notify_status + + # If the helper cannot be resolved, suppress the notification rather than + # guessing whether Windows Terminal is focused. + [[ -r $notify_script ]] || return 0 + windows_notify_script=$(command wslpath -w "$notify_script") || return 0 + [[ -n $windows_notify_script ]] || return 0 - if [[ -r $toast_script ]] && (( ${+commands[powershell.exe]} )) && (( ${+commands[wslpath]} )); then - windows_toast_script=$(command wslpath -w "$toast_script") || windows_toast_script= - if [[ -n $windows_toast_script ]] && powershell.exe -NoLogo -NoProfile -NonInteractive \ - -ExecutionPolicy Bypass -File "$windows_toast_script" \ - -Title "$title" -Message "$message" >/dev/null 2>&1; then - return - fi - fi + powershell.exe -NoLogo -NoProfile -NonInteractive \ + -ExecutionPolicy Bypass -File "$windows_notify_script" \ + -Title "$title" -Message "$message" >/dev/null 2>&1 + notify_status=$? - # Keep the old audible notification as a fallback if native toast delivery - # is unavailable or fails unexpectedly. - print -rn -- $'\a' + case $notify_status in + 0|10|11) + # Toast delivered, intentionally suppressed while focused, or focus + # state was indeterminate and the helper failed closed. + return 0 + ;; + *) + # Native delivery failed after dispatch; retain an audible fallback. + print -rn -- $'\a' + ;; + esac elif (( ${+commands[notify-send]} )); then command notify-send "$title" "$message" \ ${=icon:+--icon "$icon"} ${=bgnotify_extraargs:-} From 8ae4f4bbd26fcc3fd3594e271de6c64b4e105ed2 Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:33:00 +0800 Subject: [PATCH 03/12] test: cover WSL notification zsh syntax --- config/hk.pkl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/hk.pkl b/config/hk.pkl index e8d0945d..888c339c 100644 --- a/config/hk.pkl +++ b/config/hk.pkl @@ -23,7 +23,12 @@ local checks = new Mapping { check = "bash -n {{files}} && shellcheck -x {{files}}" } ["zsh-syntax"] { - glob = List("../home/.zshrc", "../home/.p10k.zsh") + glob = List( + "../home/.zshrc", + "../home/.p10k.zsh", + "../home/.config/sheldon/plugins/*.zsh", + "tests/*.zsh" + ) check = "zsh -n {{files}}" } } From 8aabe94e594ad6b81964bff995ced5d2f754eb8f Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:33:31 +0800 Subject: [PATCH 04/12] test: exercise WSL notification routing --- config/tests/wsl-notify.zsh | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 config/tests/wsl-notify.zsh diff --git a/config/tests/wsl-notify.zsh b/config/tests/wsl-notify.zsh new file mode 100644 index 00000000..846e9ea2 --- /dev/null +++ b/config/tests/wsl-notify.zsh @@ -0,0 +1,61 @@ +#!/usr/bin/env zsh +set -eu + +repo_root=${0:A:h:h:h} +plugin="$repo_root/home/.config/sheldon/plugins/wsl-notify.plugin.zsh" +test_root=$(mktemp -d) +trap 'rm -rf "$test_root"' EXIT +mkdir -p "$test_root/bin" + +cat >"$test_root/bin/wslpath" <<'EOF' +#!/bin/sh +printf '%s\n' 'C:\\wsl-notify.ps1' +EOF + +cat >"$test_root/bin/powershell.exe" <<'EOF' +#!/bin/sh +printf '%s\n' "$*" >>"$WSL_NOTIFY_TEST_LOG" +exit "${WSL_NOTIFY_TEST_EXIT:-0}" +EOF + +chmod +x "$test_root/bin/wslpath" "$test_root/bin/powershell.exe" + +export PATH="$test_root/bin:$PATH" +export MISE_CONFIG_DIR="$repo_root/config" +export WSL_DISTRO_NAME=ci +export WT_SESSION=ci +export WSL_NOTIFY_TEST_LOG="$test_root/powershell.log" +unset TERM_PROGRAM +rehash + +source "$plugin" + +[[ "$(bgnotify_appid)" == '__wsl_notify_dispatch__' ]] +[[ "$bgnotify_termid" == '__wsl_notify_terminal_foreground__' ]] +[[ ! -e "$WSL_NOTIFY_TEST_LOG" ]] + +for status in 0 10 11; do + export WSL_NOTIFY_TEST_EXIT=$status + output=$(bgnotify 'build finished' 'command completed' '') + [[ -z $output ]] +done + +export WSL_NOTIFY_TEST_EXIT=20 +output=$(bgnotify 'build finished' 'command completed' '') +[[ "$output" == $'\a' ]] +[[ "$(wc -l <"$WSL_NOTIFY_TEST_LOG")" -eq 4 ]] + +# Ghostty owns command-finished notifications, so the bgnotify hooks must be +# removed instead of routing through the WSL helper. +zsh -f -c ' + function bgnotify_begin {} + function bgnotify_end {} + autoload -Uz add-zsh-hook + add-zsh-hook preexec bgnotify_begin + add-zsh-hook precmd bgnotify_end + export WSL_DISTRO_NAME=ci + export TERM_PROGRAM=ghostty + source "$1" + (( ${preexec_functions[(Ie)bgnotify_begin]} == 0 )) + (( ${precmd_functions[(Ie)bgnotify_end]} == 0 )) +' zsh "$plugin" From 20116a60f6f17e92a6d5075b4889a385aca94f7e Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:33:42 +0800 Subject: [PATCH 05/12] test: run WSL notification routing checks --- config/hk.pkl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/hk.pkl b/config/hk.pkl index 888c339c..04d9ae93 100644 --- a/config/hk.pkl +++ b/config/hk.pkl @@ -31,6 +31,14 @@ local checks = new Mapping { ) check = "zsh -n {{files}}" } + ["wsl-notify"] { + glob = List( + "../home/.config/sheldon/plugins/wsl-notify.plugin.zsh", + "scripts/wsl-notify.ps1", + "tests/wsl-notify.zsh" + ) + check = "zsh tests/wsl-notify.zsh" + } } hooks { From baa1d07f694ce97b8ec762ed6f1214a97dd5348d Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:34:06 +0800 Subject: [PATCH 06/12] test: validate all PowerShell scripts --- config/hk.pkl | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/config/hk.pkl b/config/hk.pkl index 04d9ae93..133bd159 100644 --- a/config/hk.pkl +++ b/config/hk.pkl @@ -10,6 +10,45 @@ local checks = new Mapping { glob = List("scripts/*.sh") check = "sh -n {{files}}" } + ["powershell-syntax"] { + glob = List("scripts/*.ps1") + check = """ + set -e + + if command -v pwsh >/dev/null 2>&1; then + ps_cmd=pwsh + scripts_dir="$PWD/scripts" + elif command -v powershell.exe >/dev/null 2>&1 && command -v wslpath >/dev/null 2>&1; then + ps_cmd=powershell.exe + scripts_dir="$(wslpath -w "$PWD/scripts")" + else + echo 'warning: PowerShell unavailable; skipping PowerShell syntax validation' >&2 + exit 0 + fi + + "$ps_cmd" -NoLogo -NoProfile -NonInteractive -Command ' + param([string] $ScriptsDir) + $failed = $false + + Get-ChildItem -LiteralPath $ScriptsDir -Filter "*.ps1" | ForEach-Object { + $tokens = $null + $errors = $null + [System.Management.Automation.Language.Parser]::ParseFile( + $_.FullName, + [ref] $tokens, + [ref] $errors + ) | Out-Null + + if ($errors.Count -gt 0) { + $failed = $true + $errors | ForEach-Object { Write-Error "$($_.Extent.File): $_" } + } + } + + if ($failed) { exit 1 } + ' "$scripts_dir" + """ + } ["mise-tool-disables"] { glob = List("conf.d/packages.pacman.toml", "conf.d/platform.omarchy.toml") check = """ From 6b912bad76f21257beba00d9517780217dab1d4c Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:35:22 +0800 Subject: [PATCH 07/12] refactor: remove legacy WSL toast helper --- config/scripts/wsl-toast.ps1 | 42 ------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 config/scripts/wsl-toast.ps1 diff --git a/config/scripts/wsl-toast.ps1 b/config/scripts/wsl-toast.ps1 deleted file mode 100644 index 94637f2e..00000000 --- a/config/scripts/wsl-toast.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -param( - [Parameter(Mandatory = $true)][string] $Title, - [Parameter(Mandatory = $true)][string] $Message -) - -$ErrorActionPreference = 'Stop' -Set-StrictMode -Version Latest - -Add-Type -AssemblyName System.Runtime.WindowsRuntime -$null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] -$null = [Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] -$null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] - -$startApps = @(Get-StartApps) -$appId = $startApps | - Where-Object { $_.AppID -eq 'Microsoft.WindowsTerminal_8wekyb3d8bbwe!App' } | - Select-Object -First 1 -ExpandProperty AppID - -if ([string]::IsNullOrWhiteSpace($appId)) { - $appId = $startApps | - Where-Object { $_.AppID -match '^Microsoft\.WindowsTerminal.*!App$' } | - Select-Object -First 1 -ExpandProperty AppID -} - -if ([string]::IsNullOrWhiteSpace($appId)) { - $appId = $startApps | - Where-Object { $_.AppID -match 'PowerShell' } | - Select-Object -First 1 -ExpandProperty AppID -} - -if ([string]::IsNullOrWhiteSpace($appId)) { - throw 'No Start-menu AUMID suitable for WSL toast notifications was found.' -} - -$document = [Windows.Data.Xml.Dom.XmlDocument]::new() -$document.LoadXml('') -$textNodes = $document.GetElementsByTagName('text') -[void] $textNodes.Item(0).AppendChild($document.CreateTextNode($Title)) -[void] $textNodes.Item(1).AppendChild($document.CreateTextNode($Message)) - -$toast = [Windows.UI.Notifications.ToastNotification]::new($document) -[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($appId).Show($toast) From 7075cb85f5674bbe95b60ede62c4ef248b58d96c Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:36:39 +0800 Subject: [PATCH 08/12] test: avoid reserved zsh status parameter --- config/tests/wsl-notify.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/tests/wsl-notify.zsh b/config/tests/wsl-notify.zsh index 846e9ea2..8bc1f83e 100644 --- a/config/tests/wsl-notify.zsh +++ b/config/tests/wsl-notify.zsh @@ -34,8 +34,8 @@ source "$plugin" [[ "$bgnotify_termid" == '__wsl_notify_terminal_foreground__' ]] [[ ! -e "$WSL_NOTIFY_TEST_LOG" ]] -for status in 0 10 11; do - export WSL_NOTIFY_TEST_EXIT=$status +for exit_code in 0 10 11; do + export WSL_NOTIFY_TEST_EXIT=$exit_code output=$(bgnotify 'build finished' 'command completed' '') [[ -z $output ]] done From def566b005783f71b04f86b9fdbf093759384a26 Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:37:51 +0800 Subject: [PATCH 09/12] fix: preserve WSL notification helper status under errexit --- home/.config/sheldon/plugins/wsl-notify.plugin.zsh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/home/.config/sheldon/plugins/wsl-notify.plugin.zsh b/home/.config/sheldon/plugins/wsl-notify.plugin.zsh index adee4a3c..a1e0955c 100644 --- a/home/.config/sheldon/plugins/wsl-notify.plugin.zsh +++ b/home/.config/sheldon/plugins/wsl-notify.plugin.zsh @@ -47,10 +47,13 @@ function bgnotify { windows_notify_script=$(command wslpath -w "$notify_script") || return 0 [[ -n $windows_notify_script ]] || return 0 - powershell.exe -NoLogo -NoProfile -NonInteractive \ + if powershell.exe -NoLogo -NoProfile -NonInteractive \ -ExecutionPolicy Bypass -File "$windows_notify_script" \ - -Title "$title" -Message "$message" >/dev/null 2>&1 - notify_status=$? + -Title "$title" -Message "$message" >/dev/null 2>&1; then + notify_status=0 + else + notify_status=$? + fi case $notify_status in 0|10|11) From 4b6572cca92935c2dbdfc4c6ff0aa87c8e276761 Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:40:07 +0800 Subject: [PATCH 10/12] test: isolate Ghostty hook removal fixture --- config/tests/wsl-notify.zsh | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/config/tests/wsl-notify.zsh b/config/tests/wsl-notify.zsh index 8bc1f83e..6079742b 100644 --- a/config/tests/wsl-notify.zsh +++ b/config/tests/wsl-notify.zsh @@ -45,17 +45,31 @@ output=$(bgnotify 'build finished' 'command completed' '') [[ "$output" == $'\a' ]] [[ "$(wc -l <"$WSL_NOTIFY_TEST_LOG")" -eq 4 ]] -# Ghostty owns command-finished notifications, so the bgnotify hooks must be -# removed instead of routing through the WSL helper. +# Exercise the Ghostty hook-removal path without depending on the runner's zsh +# function installation. The fixture is loaded through zsh's real autoload +# mechanism, just like add-zsh-hook is in an interactive shell. +mkdir -p "$test_root/fpath" +cat >"$test_root/fpath/add-zsh-hook" <<'EOF' +local mode=$1 hook=$2 callback=$3 +[[ $mode == -d ]] || return 2 + +case $hook in + preexec) preexec_functions=(${preexec_functions:#$callback}) ;; + precmd) precmd_functions=(${precmd_functions:#$callback}) ;; + *) return 2 ;; +esac +EOF + zsh -f -c ' + typeset -ga preexec_functions precmd_functions + preexec_functions=(bgnotify_begin) + precmd_functions=(bgnotify_end) function bgnotify_begin {} function bgnotify_end {} - autoload -Uz add-zsh-hook - add-zsh-hook preexec bgnotify_begin - add-zsh-hook precmd bgnotify_end + fpath=("$2" $fpath) export WSL_DISTRO_NAME=ci export TERM_PROGRAM=ghostty source "$1" (( ${preexec_functions[(Ie)bgnotify_begin]} == 0 )) (( ${precmd_functions[(Ie)bgnotify_end]} == 0 )) -' zsh "$plugin" +' zsh "$plugin" "$test_root/fpath" From 1d49e307e545878ad4097e373d95cbe6a1b5d466 Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:41:12 +0800 Subject: [PATCH 11/12] test: assert removed Ghostty hooks safely --- config/tests/wsl-notify.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/tests/wsl-notify.zsh b/config/tests/wsl-notify.zsh index 6079742b..eb141ee3 100644 --- a/config/tests/wsl-notify.zsh +++ b/config/tests/wsl-notify.zsh @@ -70,6 +70,6 @@ zsh -f -c ' export WSL_DISTRO_NAME=ci export TERM_PROGRAM=ghostty source "$1" - (( ${preexec_functions[(Ie)bgnotify_begin]} == 0 )) - (( ${precmd_functions[(Ie)bgnotify_end]} == 0 )) + [[ -z ${preexec_functions[(r)bgnotify_begin]-} ]] + [[ -z ${precmd_functions[(r)bgnotify_end]-} ]] ' zsh "$plugin" "$test_root/fpath" From d137f1c6ac2464a01a2556101e989222b88ba2c6 Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 14 Sep 2026 10:42:43 +0800 Subject: [PATCH 12/12] test: bind PowerShell syntax-check arguments --- config/hk.pkl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/hk.pkl b/config/hk.pkl index 133bd159..5612e9a3 100644 --- a/config/hk.pkl +++ b/config/hk.pkl @@ -26,7 +26,7 @@ local checks = new Mapping { exit 0 fi - "$ps_cmd" -NoLogo -NoProfile -NonInteractive -Command ' + "$ps_cmd" -NoLogo -NoProfile -NonInteractive -Command '& { param([string] $ScriptsDir) $failed = $false @@ -46,7 +46,7 @@ local checks = new Mapping { } if ($failed) { exit 1 } - ' "$scripts_dir" + }' "$scripts_dir" """ } ["mise-tool-disables"] {