residoo 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "residoo",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Find secrets leaking through your AI coding agent's session history. Zero network calls in the scan path, zero dependencies.",
5
5
  "license": "MIT",
6
6
  "author": "CloudRoam (https://cloudroam.io)",
package/src/cli.js CHANGED
@@ -186,8 +186,8 @@ Watch:
186
186
  same meaning as scan
187
187
  --no-notify skip the OS desktop notification watch fires for
188
188
  each genuinely new finding (macOS via osascript,
189
- Linux via notify-send if installed; no built-in
190
- mechanism on Windows -- disclosed, not attempted).
189
+ Linux via notify-send if installed, Windows via
190
+ System.Windows.Forms.NotifyIcon's balloon-tip API).
191
191
  On by default in human-readable mode: watch's own
192
192
  purpose is alerting you, and a background process
193
193
  nobody is watching a terminal for needs more than
package/src/notify.js CHANGED
@@ -8,13 +8,8 @@ const cp = require("child_process");
8
8
  * precedent `keychain.js`'s `security` and `ocr.js`'s `tesseract` already
9
9
  * set), Linux via `notify-send` (commonly present on a desktop session,
10
10
  * NOT guaranteed -- `watch` also runs on headless/server machines with no
11
- * notification daemon at all).
12
- *
13
- * Windows: no built-in, dependency-free mechanism was found that doesn't
14
- * either need an external module (BurntToast) or pop a blocking, modal
15
- * MessageBox in front of a background process -- a disclosed scope limit,
16
- * not silently assumed covered, the same posture `keychain.js` already
17
- * takes for its own Windows refusal.
11
+ * notification daemon at all), Windows via `System.Windows.Forms.NotifyIcon`'s
12
+ * balloon-tip API (see the Windows-specific docstring below).
18
13
  *
19
14
  * Decoration, never the report itself: `watch`'s own `emit()` already
20
15
  * writes every finding to stdout/stderr before this is ever called, so a
@@ -43,11 +38,63 @@ function notifyDesktop(title, message) {
43
38
  const child = cp.spawn("notify-send", [String(title), String(message)], { stdio: "ignore" });
44
39
  child.on("error", () => {});
45
40
  child.unref();
41
+ } else if (process.platform === "win32") {
42
+ notifyWindows(title, message);
46
43
  }
47
- // Windows and anything else: no-op, disclosed above, not attempted.
44
+ // Anything else: no-op, not attempted.
48
45
  } catch {
49
46
  // Never let a notification failure affect the caller.
50
47
  }
51
48
  }
52
49
 
50
+ /**
51
+ * Windows desktop notification via `System.Windows.Forms.NotifyIcon`'s
52
+ * balloon-tip API, shelled out to `powershell.exe` -- an earlier version
53
+ * of this module considered WinRT toast interop
54
+ * (`[Windows.UI.Notifications.ToastNotificationManager]`) instead and
55
+ * declined it after research found a real, disqualifying prerequisite:
56
+ * Microsoft's own docs make a Start-menu shortcut carrying a registered
57
+ * AppUserModelID a hard requirement for ANY desktop app's toast to
58
+ * display at all, explicitly including unpackaged/scripted apps. NotifyIcon
59
+ * has no such requirement -- confirmed against Microsoft's own current API
60
+ * reference (no [Obsolete] marker, listed through the windowsdesktop-10.0/
61
+ * 11.0 monikers) and multiple independently-converging technique
62
+ * write-ups, one of which states plainly it "requires no Start-menu
63
+ * shortcuts, AUMID registration, or external PowerShell modules." Not
64
+ * live-tested against a real Windows install, the same disclosed
65
+ * limitation `keychain.js`'s DPAPI functions and `integrity.js`'s Get-Acl
66
+ * check already carry.
67
+ *
68
+ * Two real caveats, disclosed rather than smoothed over: Windows ignores
69
+ * the millisecond value passed to `ShowBalloonTip` (actual on-screen
70
+ * duration is governed by the user's own accessibility settings, not this
71
+ * script), and the tray icon does NOT self-remove -- every reference
72
+ * implementation found demonstrates disposal via an interactive
73
+ * double-click handler, not an automatic one, which does not exist for a
74
+ * non-interactive script. This is why the script below explicitly
75
+ * `Start-Sleep`s before calling `.Dispose()` itself, inside the SAME
76
+ * spawned process: `notifyDesktop` never blocks its caller (the sleep
77
+ * happens in a detached, `unref()`'d child, exactly like the macOS/Linux
78
+ * branches above), but something has to keep the icon alive long enough
79
+ * to actually be seen before removing it, and nothing outside that one
80
+ * process is positioned to send a follow-up "now dispose" signal.
81
+ */
82
+ function notifyWindows(title, message) {
83
+ const esc = (s) => String(s).replace(/'/g, "''");
84
+ const script =
85
+ "Add-Type -AssemblyName System.Windows.Forms; " +
86
+ "Add-Type -AssemblyName System.Drawing; " +
87
+ "$ni = New-Object System.Windows.Forms.NotifyIcon; " +
88
+ "$ni.Icon = [System.Drawing.SystemIcons]::Information; " +
89
+ `$ni.BalloonTipTitle = '${esc(title)}'; ` +
90
+ `$ni.BalloonTipText = '${esc(message)}'; ` +
91
+ "$ni.Visible = $true; " +
92
+ "$ni.ShowBalloonTip(10000); " +
93
+ "Start-Sleep -Seconds 10; " +
94
+ "$ni.Dispose()";
95
+ const child = cp.spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-WindowStyle", "Hidden", "-Command", script], { stdio: "ignore" });
96
+ child.on("error", () => {});
97
+ child.unref();
98
+ }
99
+
53
100
  module.exports = { notifyDesktop };