Skip to content

feat(hooks): add WSL desktop notification support via PowerShell + BurntToast#1019

Merged
affaan-m merged 10 commits into
affaan-m:mainfrom
QWsin:fix/desktop-notify-wsl
Mar 30, 2026
Merged

feat(hooks): add WSL desktop notification support via PowerShell + BurntToast#1019
affaan-m merged 10 commits into
affaan-m:mainfrom
QWsin:fix/desktop-notify-wsl

Conversation

@QWsin

@QWsin QWsin commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

What Changed

Added WSL (Windows Subsystem for Linux) desktop notification support to the existing desktop-notify.js hook.

New functions:

  • isWSL(): detects WSL environment
  • findPowerShell(): finds PowerShell 7 or Windows PowerShell on WSL
  • isBurntToastAvailable(): checks if BurntToast module is installed
  • notifyWindows(): sends Windows toast notification via BurntToast

Platforms:

  • macOS: osascript (existing)
  • WSL: PowerShell + BurntToast (new)

If BurntToast is not installed, logs helpful tip for installation. Falls back silently on non-WSL/non-macOS platforms.

Why This Change

Users running Claude Code in WSL couldn't receive desktop notifications since the existing code only supported macOS. This change enables Windows native notifications for WSL users.

Testing Done

  • Manual testing completed (PowerShell 7 + BurntToast confirmed working)
  • Automated tests pass locally (node tests/run-all.js - 1683 pass, 1 unrelated failure)
  • Edge cases handled (no PowerShell, BurntToast not installed, timeouts)

Type of Change

  • feat: New feature

Security & Quality Checklist

  • No secrets or API keys committed
  • JSON files validate cleanly
  • No sensitive data exposed in logs or output
  • Follows conventional commits format

Documentation

  • Updated comments for complex logic
  • Updated file header documentation

Summary by cubic

Adds WSL desktop notifications in desktop-notify.js using PowerShell and BurntToast, with improved detection and clearer error messages. Also updates hooks.json to mention macOS/WSL support and speeds up notifications by reducing PowerShell spawns.

  • New Features

    • Detects WSL and finds PowerShell (7 or Windows PowerShell).
    • Sends Windows toasts via BurntToast; logs an install tip if the module is missing.
    • macOS path unchanged; hooks.json now mentions macOS/WSL.
  • Bug Fixes

    • More robust detection: memoize WSL checks, prefer WSL interop PATH, and increase PowerShell probe timeout to 3s.
    • Better errors: capture stderr and return an error reason from notifyWindows; log actionable messages and only show the BurntToast tip when relevant.
    • Cleanup and perf: reduce PowerShell spawns from 3 to 1, remove a duplicate function, and tidy tips (quote PowerShell path; remove external URL).

Written for commit 804d51d. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Desktop notifications now work on macOS and WSL (attempts Windows toast via PowerShell/BurntToast) with improved platform detection and conditional fallbacks.
  • Documentation
    • Added user-facing setup tips when PowerShell or BurntToast is missing.
    • Updated hook description to reference macOS/WSL notification support.

…ntToast

Adds WSL (Windows Subsystem for Linux) desktop notification support to the
existing desktop-notify hook. The hook now detects WSL, finds available
PowerShell (7 or Windows PowerShell), checks for BurntToast module, and
sends Windows toast notifications.

New functions:
- isWSL(): detects WSL environment
- findPowerShell(): finds PowerShell 7 or Windows PowerShell on WSL
- isBurntToastAvailable(): checks if BurntToast module is installed
- notifyWindows(): sends Windows toast notification via BurntToast

If BurntToast is not installed, logs helpful tip for installation.
Falls back silently on non-WSL/non-macOS platforms.
@coderabbitai

coderabbitai Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds WSL support to the desktop notification hook: detects WSL, locates PowerShell, attempts BurntToast-based Windows toasts via PowerShell, falls back to logging install guidance, and still sends native macOS notifications when on macOS.

Changes

Cohort / File(s) Summary
Desktop Notification Hook
scripts/hooks/desktop-notify.js
Removed macOS-only early return; added memoized WSL detection (checks /proc/version), PowerShell discovery (findPowerShell probing pwsh.exe/powershell.exe candidates), BurntToast-based Windows toast dispatch via PowerShell (Import-Module BurntToast + New-BurntToastNotification), single-quote escaping for payloads, updated control flow to always parse input and conditionally notify on macOS or WSL, and added logging guidance for missing PowerShell/BurntToast.
Hook Metadata
hooks/hooks.json
Updated "stop:desktop-notify" hook description text to reflect macOS and WSL support (documentation string change only).

Sequence Diagram

sequenceDiagram
    participant Client
    participant Hook as run(raw)
    participant Platform as PlatformCheck
    participant WSL as WSLCheck
    participant PS as PowerShellFinder
    participant BT as BurntToastCheck
    participant Windows as WindowsToast

    Client->>Hook: invoke run(raw)
    Hook->>Platform: is macOS?
    alt macOS
        Platform-->>Hook: true
        Hook->>Windows: send macOS native notification
    else not macOS
        Platform-->>Hook: false
        Hook->>WSL: check /proc/version contains "microsoft"
        alt WSL
            WSL-->>Hook: true
            Hook->>PS: probe candidate pwsh/powershell paths
            alt PowerShell found
                PS-->>Hook: pwsh path
                Hook->>BT: run PowerShell to Import-Module BurntToast
                alt BurntToast import succeeds
                    BT-->>Hook: loaded
                    Hook->>Windows: New-BurntToastNotification(title, body)
                    Windows-->>Hook: result
                else BurntToast import fails
                    BT-->>Hook: import failed
                    Hook-->>Client: log BurntToast installation guidance
                end
            else PowerShell not found
                PS-->>Hook: not found
                Hook-->>Client: log PowerShell/BurntToast guidance
            end
        else not WSL
            WSL-->>Hook: false
            Hook-->>Client: no-op / preserved macOS behavior
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped from macOS to WSL shore,
I sniffed for pwsh and knocked on BurntToast's door,
If PowerShell sings, a toast will bloom,
else gentle logs light up the room,
a rabbit cheers the CI with a boom.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: adding WSL desktop notification support via PowerShell and BurntToast, which aligns with the primary modifications in desktop-notify.js and the updated hook description.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds WSL desktop notification support to desktop-notify.js by introducing PowerShell detection (findPowerShell) and a toast-notification sender (notifyWindows) that uses the BurntToast PowerShell module. The hook now branches on isMacOS vs isWSL and exits silently on all other platforms.

All six previously flagged P1 issues are resolved in this iteration:

  • stdio is now properly piped in notifyWindows so result.stderr is captured
  • findPowerShell probes WSL interop-resolved names (pwsh.exe, powershell.exe) before hardcoded /mnt/c/ paths
  • WSL detection is memoized at module load, eliminating repeated /proc/version reads
  • The duplicate notifyWindows declaration (which would have caused a SyntaxError) is gone
  • notifyWindows now returns { success, reason } so the caller can distinguish success from BurntToast-not-installed from other errors
  • PowerShell spawn count is reduced from 3 to 2 per notification

Remaining minor issue:

  • The tip logged when no PowerShell binary is found tells the user to "Install BurntToast module in PowerShell" — but the real problem is that PowerShell itself isn't installed. The message should guide the user to install PowerShell first.

Confidence Score: 5/5

Safe to merge; all prior P1 issues are resolved and only a minor tip-text wording issue remains.

All six previously raised P1 findings (SyntaxError from duplicate declaration, missing return value, stdio discard, hardcoded C: drive, double isWSL reads, excessive spawns) are addressed in the current commit. The single remaining finding is a P2 UX string issue that does not affect correctness or reliability. Per the confidence guidance, a P2-only result warrants 5/5.

No files require special attention for merge safety.

Important Files Changed

Filename Overview
scripts/hooks/desktop-notify.js Adds WSL notification support via PowerShell + BurntToast; all previously flagged P1 issues resolved (stdio piping, memoized WSL detection, duplicate declaration, missing return value, hardcoded C: drive). One minor P2 remains: misleading tip message when PowerShell itself is absent.
hooks/hooks.json Trivial one-line description update to reflect macOS/WSL support — no logic changes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[run] --> B{isMacOS?}
    B -- yes --> C[notifyMacOS via osascript]
    B -- no --> D{isWSL?}
    D -- no --> E[silent return]
    D -- yes --> F[findPowerShell]
    F --> G{found?}
    G -- null --> H[log install PowerShell tip]
    G -- path --> I[notifyWindows via BurntToast]
    I --> J{success?}
    J -- true --> K[notification sent]
    J -- reason has burnttoast --> L[log install BurntToast tip]
    J -- other reason --> M[log notification failed]
Loading

Reviews (6): Last reviewed commit: "fix(hooks): improve error handling and d..." | Re-trigger Greptile

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/hooks/desktop-notify.js">

<violation number="1" location="scripts/hooks/desktop-notify.js:144">
P2: Installation tip command is not shell-safe: PowerShell path is unquoted even though candidate path contains spaces.</violation>

<violation number="2" location="scripts/hooks/desktop-notify.js:148">
P2: User-facing runtime output includes a direct external repository link, conflicting with the project policy against unvetted external repo links.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread scripts/hooks/desktop-notify.js Outdated
Comment thread scripts/hooks/desktop-notify.js Outdated
Comment thread scripts/hooks/desktop-notify.js Outdated
Comment thread scripts/hooks/desktop-notify.js
Comment thread scripts/hooks/desktop-notify.js Outdated
Comment thread scripts/hooks/desktop-notify.js Outdated
Updates the hook description in hooks.json to reflect the newly
added WSL notification support alongside macOS.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/hooks/desktop-notify.js`:
- Around line 6-10: Update the hooks registry entry for the "desktop-notify"
hook in hooks.json so its description matches scripts/hooks/desktop-notify.js:
change the metadata text (currently macOS-only) to advertise both macOS
(osascript) and WSL (PowerShell 7 or Windows PowerShell + BurntToast), and
mention the WSL tip when BurntToast is missing so the catalog/help text aligns
with the hook's actual behavior.
- Around line 41-47: findPowerShell currently only checks hard-coded /mnt/c/...
paths so it can miss valid WSL setups; update findPowerShell to first probe for
executables by name (try "pwsh.exe" then "powershell.exe") using a PATH/command
lookup (e.g., child_process.execSync('command -v ...') or fs access via
which-like resolution) and return the first found, and only if those fail fall
back to the existing candidates array of absolute paths; keep the isWSL() guard
and preserve the original candidates list so the function still handles systems
where executables are not on PATH.
- Around line 67-75: isBurntToastAvailable currently swallows all errors and
returns a boolean, and notifyWindows uses stdio: 'ignore' then reads
result.stderr (null); change isBurntToastAvailable to return an object like {
available, reason } where you set available = true when exit code 0, available =
false and reason = stderr/exception message when non-zero/exception, and adjust
spawnSync stdio to ['ignore','pipe','pipe'] to capture stderr; then update
callers (e.g., the call at the former line 139) to check .available and use the
.reason when logging errors and only show the BurntToast install guidance when
reason indicates the module is missing rather than for timeouts or other
failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dbce2581-c602-4597-b965-4f76755e0a5e

📥 Commits

Reviewing files that changed from the base of the PR and between 8846210 and a57c3c5.

📒 Files selected for processing (1)
  • scripts/hooks/desktop-notify.js

Comment thread scripts/hooks/desktop-notify.js
Comment thread scripts/hooks/desktop-notify.js
Comment thread scripts/hooks/desktop-notify.js Outdated
Change stdio to ['ignore', 'pipe', 'pipe'] so stderr is captured
and can be logged on errors. Without this, result.stderr is null
and error logs show 'undefined' instead of the actual error.
@QWsin

QWsin commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Addressing the points:

Issue #1 (stderr): Fixed in latest commit. Changed stdio: 'ignore' to stdio: ['ignore', 'pipe', 'pipe'] so stderr is captured and logged properly on errors.

Issue #2 (hardcoded paths): Valid P2 concern. The current implementation covers the default WSL installation path. Non-default mounts would need additional path probing - keeping as P2 for a follow-up improvement.

Issue #3 (isWSL() called twice): Acknowledged as P2 optimization. Could memoize the result, but the I/O is minimal.

Issue #4 (sequential spawnSync): Acknowledged as P2 perf concern. The hook runs async so it doesn't block Claude Code.

Thanks for the thorough review!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/hooks/desktop-notify.js (1)

55-55: version is computed but never used.

findPowerShell() returns { path, version }, but version is not referenced anywhere in the codebase. Consider removing the version probing if it's not planned for near-term use, or add a comment indicating future intent.

♻️ Option A: Simplify if version is unneeded
   for (const path of candidates) {
     try {
-      const result = spawnSync(path, ['-Command', '$PSVersionTable.PSVersion.Major'],
+      const result = spawnSync(path, ['-Command', '$true'],
         { stdio: ['ignore', 'pipe', 'ignore'], timeout: 3000 });
       if (result.status === 0) {
-        const version = parseInt(result.stdout.toString().trim(), 10);
-        return { path, version };
+        return { path };
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/hooks/desktop-notify.js` at line 55, findPowerShell() currently
returns an object with { path, version } but the computed version value is never
used; either remove the version probing and change the return to only supply
path (and update any callers that destructure the result) or keep the probe but
add a clear TODO/comment explaining future intent and mark the version as
intentionally unused; update the findPowerShell function (and any code that
handles its return) to reflect the chosen approach so there are no unused
variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/hooks/desktop-notify.js`:
- Line 55: findPowerShell() currently returns an object with { path, version }
but the computed version value is never used; either remove the version probing
and change the return to only supply path (and update any callers that
destructure the result) or keep the probe but add a clear TODO/comment
explaining future intent and mark the version as intentionally unused; update
the findPowerShell function (and any code that handles its return) to reflect
the chosen approach so there are no unused variables.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 58dd876a-83ea-4662-b1ea-0286b33d1c3d

📥 Commits

Reviewing files that changed from the base of the PR and between d9d16a0 and 2c1ae27.

📒 Files selected for processing (1)
  • scripts/hooks/desktop-notify.js

QWsin added 5 commits March 30, 2026 14:07
The PowerShell path contains spaces and needs to be quoted
when displayed as a copy-pasteable command.
BurntToast module is a well-known Microsoft module but per project
policy avoiding unvetted external links in user-facing output.
Adds 'pwsh.exe' and 'powershell.exe' as candidates to leverage
WSL's Windows interop PATH resolution, making the hook work with
non-default WSL mount prefixes or Windows drives.
Avoids reading /proc/version twice (once in run(), once in findPowerShell())
by computing the result once when the module loads.
Merge findPowerShell version check and isBurntToastAvailable check
into a single notifyWindows call. Now just tries to send directly;
if it fails, tries next PowerShell path. Version field was unused.

Net effect: up to 3 spawns reduced to 1 in the happy path.
@QWsin

QWsin commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review! Here's a summary of all P2 issues addressed:

1. stderr capture (notifyWindows)

  • Fixed: Changed stdio: 'ignore' to stdio: ['ignore', 'pipe', 'pipe'] so stderr is captured for error logging

2. Shell safety (install tip)

  • Fixed: Added quotes around PowerShell path in install tip: "\${ps.path}"

3. External repo URL

  • Fixed: Removed https://github.com/microsoft/BurntToast from user-facing tip per project policy

4. Hardcoded C: drive / WSL mount prefix

  • Fixed: Added pwsh.exe and powershell.exe as candidates first to leverage WSL interop PATH resolution

5. isWSL() called twice

  • Fixed: Memoized WSL detection at module load time instead of calling isWSL() in both run() and findPowerShell()

6. Sequential PowerShell spawns (3 → 1)

  • Fixed: Refactored to single spawn per notification. Removed isBurntToastAvailable() and merged into notifyWindows(). Now tries to send directly; if it fails we try the next PowerShell path. Version field was unused and removed.

All P2 issues have been addressed. Thanks again for the detailed review!

Comment thread scripts/hooks/desktop-notify.js
Comment thread scripts/hooks/desktop-notify.js Outdated
There were two notifyWindows function declarations due to incomplete
refactoring. Keeps only the version that returns true/false for the
call site. Node.js would throw SyntaxError with 'use strict'.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
scripts/hooks/desktop-notify.js (1)

137-145: ⚠️ Potential issue | 🟠 Major

Don't collapse all WSL failures into the BurntToast install tip.

Lines 141-144 still tell users to install BurntToast when either PowerShell was not found at all or toast delivery failed for some other reason. That sends users to the wrong remediation path; only print the BurntToast tip when the underlying PowerShell failure actually indicates a missing module, and use a PowerShell-specific message for the !ps case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/hooks/desktop-notify.js` around lines 137 - 145, The current branch
collapses all failures into the BurntToast tip; change the flow to call
notifyWindows(ps, TITLE, summary) only when ps is truthy and inspect its result
(e.g., const result = notifyWindows(ps, TITLE, summary)); have notifyWindows
return a distinct value or error reason such as 'missingBurntToast' or
true/false so you can: if (ps && result === true) do nothing, else if (ps &&
result === 'missingBurntToast') log the BurntToast install tip, else if (ps) log
a PowerShell-specific failure message (toast delivery failed), and finally if
(!ps) log the PowerShell-not-found tip; update notifyWindows and the call site
(ps, notifyWindows, TITLE, summary, log) accordingly so each case maps to the
correct remediation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@scripts/hooks/desktop-notify.js`:
- Around line 137-145: The current branch collapses all failures into the
BurntToast tip; change the flow to call notifyWindows(ps, TITLE, summary) only
when ps is truthy and inspect its result (e.g., const result = notifyWindows(ps,
TITLE, summary)); have notifyWindows return a distinct value or error reason
such as 'missingBurntToast' or true/false so you can: if (ps && result === true)
do nothing, else if (ps && result === 'missingBurntToast') log the BurntToast
install tip, else if (ps) log a PowerShell-specific failure message (toast
delivery failed), and finally if (!ps) log the PowerShell-not-found tip; update
notifyWindows and the call site (ps, notifyWindows, TITLE, summary, log)
accordingly so each case maps to the correct remediation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ef186afe-74b1-4752-8c91-f86c8665f930

📥 Commits

Reviewing files that changed from the base of the PR and between 2c1ae27 and 99ff568.

📒 Files selected for processing (1)
  • scripts/hooks/desktop-notify.js

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/hooks/desktop-notify.js">

<violation number="1" location="scripts/hooks/desktop-notify.js:53">
P2: PowerShell detection timeout was tightened to 1s, which can cause false negatives on slower/cold WSL interop startup and skip notifications.</violation>

<violation number="2" location="scripts/hooks/desktop-notify.js:127">
P2: WSL notification failures are now always reported as “BurntToast not available,” and error details are dropped. Any PowerShell/notification error returns false and triggers the install tip, masking actionable diagnostics for non-module failures.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread scripts/hooks/desktop-notify.js Outdated
Comment thread scripts/hooks/desktop-notify.js Outdated
- Increase PowerShell detection timeout from 1s to 3s to avoid false
  negatives on slower/cold WSL interop startup
- Return error reason from notifyWindows to distinguish BurntToast
  module not found vs other PowerShell errors
- Log actionable error details instead of always showing install tip
@affaan-m affaan-m merged commit 118e57e into affaan-m:main Mar 30, 2026
4 checks passed
peiking88 pushed a commit to peiking88/everything-claude-code that referenced this pull request Apr 4, 2026
…rntToast (affaan-m#1019)

* fix(hooks): add WSL desktop notification support via PowerShell + BurntToast

Adds WSL (Windows Subsystem for Linux) desktop notification support to the
existing desktop-notify hook. The hook now detects WSL, finds available
PowerShell (7 or Windows PowerShell), checks for BurntToast module, and
sends Windows toast notifications.

New functions:
- isWSL(): detects WSL environment
- findPowerShell(): finds PowerShell 7 or Windows PowerShell on WSL
- isBurntToastAvailable(): checks if BurntToast module is installed
- notifyWindows(): sends Windows toast notification via BurntToast

If BurntToast is not installed, logs helpful tip for installation.
Falls back silently on non-WSL/non-macOS platforms.

* docs(hooks): update desktop-notify description to include WSL

Updates the hook description in hooks.json to reflect the newly
added WSL notification support alongside macOS.

* fix(hooks): capture stderr properly in notifyWindows

Change stdio to ['ignore', 'pipe', 'pipe'] so stderr is captured
and can be logged on errors. Without this, result.stderr is null
and error logs show 'undefined' instead of the actual error.

* fix(hooks): quote PowerShell path in install tip for shell safety

The PowerShell path contains spaces and needs to be quoted
when displayed as a copy-pasteable command.

* fix(hooks): remove external repo URL from tip message

BurntToast module is a well-known Microsoft module but per project
policy avoiding unvetted external links in user-facing output.

* fix(hooks): probe WSL interop PATH before hardcoded paths

Adds 'pwsh.exe' and 'powershell.exe' as candidates to leverage
WSL's Windows interop PATH resolution, making the hook work with
non-default WSL mount prefixes or Windows drives.

* perf(hooks): memoize isWSL detection at module load

Avoids reading /proc/version twice (once in run(), once in findPowerShell())
by computing the result once when the module loads.

* perf(hooks): reduce PowerShell spawns from 3 to 1 per notification

Merge findPowerShell version check and isBurntToastAvailable check
into a single notifyWindows call. Now just tries to send directly;
if it fails, tries next PowerShell path. Version field was unused.

Net effect: up to 3 spawns reduced to 1 in the happy path.

* fix(hooks): remove duplicate notifyWindows declaration

There were two notifyWindows function declarations due to incomplete
refactoring. Keeps only the version that returns true/false for the
call site. Node.js would throw SyntaxError with 'use strict'.

* fix(hooks): improve error handling and detection robustness

- Increase PowerShell detection timeout from 1s to 3s to avoid false
  negatives on slower/cold WSL interop startup
- Return error reason from notifyWindows to distinguish BurntToast
  module not found vs other PowerShell errors
- Log actionable error details instead of always showing install tip

---------

Co-authored-by: boss <boss@example.com>
FrancescoRosciano pushed a commit to FRosciano-Mambo/everything-claude-code that referenced this pull request Jun 1, 2026
…rntToast (affaan-m#1019)

* fix(hooks): add WSL desktop notification support via PowerShell + BurntToast

Adds WSL (Windows Subsystem for Linux) desktop notification support to the
existing desktop-notify hook. The hook now detects WSL, finds available
PowerShell (7 or Windows PowerShell), checks for BurntToast module, and
sends Windows toast notifications.

New functions:
- isWSL(): detects WSL environment
- findPowerShell(): finds PowerShell 7 or Windows PowerShell on WSL
- isBurntToastAvailable(): checks if BurntToast module is installed
- notifyWindows(): sends Windows toast notification via BurntToast

If BurntToast is not installed, logs helpful tip for installation.
Falls back silently on non-WSL/non-macOS platforms.

* docs(hooks): update desktop-notify description to include WSL

Updates the hook description in hooks.json to reflect the newly
added WSL notification support alongside macOS.

* fix(hooks): capture stderr properly in notifyWindows

Change stdio to ['ignore', 'pipe', 'pipe'] so stderr is captured
and can be logged on errors. Without this, result.stderr is null
and error logs show 'undefined' instead of the actual error.

* fix(hooks): quote PowerShell path in install tip for shell safety

The PowerShell path contains spaces and needs to be quoted
when displayed as a copy-pasteable command.

* fix(hooks): remove external repo URL from tip message

BurntToast module is a well-known Microsoft module but per project
policy avoiding unvetted external links in user-facing output.

* fix(hooks): probe WSL interop PATH before hardcoded paths

Adds 'pwsh.exe' and 'powershell.exe' as candidates to leverage
WSL's Windows interop PATH resolution, making the hook work with
non-default WSL mount prefixes or Windows drives.

* perf(hooks): memoize isWSL detection at module load

Avoids reading /proc/version twice (once in run(), once in findPowerShell())
by computing the result once when the module loads.

* perf(hooks): reduce PowerShell spawns from 3 to 1 per notification

Merge findPowerShell version check and isBurntToastAvailable check
into a single notifyWindows call. Now just tries to send directly;
if it fails, tries next PowerShell path. Version field was unused.

Net effect: up to 3 spawns reduced to 1 in the happy path.

* fix(hooks): remove duplicate notifyWindows declaration

There were two notifyWindows function declarations due to incomplete
refactoring. Keeps only the version that returns true/false for the
call site. Node.js would throw SyntaxError with 'use strict'.

* fix(hooks): improve error handling and detection robustness

- Increase PowerShell detection timeout from 1s to 3s to avoid false
  negatives on slower/cold WSL interop startup
- Return error reason from notifyWindows to distinguish BurntToast
  module not found vs other PowerShell errors
- Log actionable error details instead of always showing install tip

---------

Co-authored-by: boss <boss@example.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants