| 120 | let _gitleaksAvailability: boolean | null = null; |
| 121 | |
| 122 | function gitleaksAvailable(): boolean { |
| 123 | if (_gitleaksAvailability !== null) return _gitleaksAvailability; |
| 124 | try { |
| 125 | execFileSync("gitleaks", ["version"], { |
| 126 | env: process.env, |
| 127 | stdio: "ignore", |
| 128 | timeout: 2_000, |
| 129 | }); |
| 130 | _gitleaksAvailability = true; |
| 131 | } catch { |
| 132 | _gitleaksAvailability = false; |
| 133 | // Only warn once per process — Lane E will vendor the binary. |
| 134 | process.stderr.write( |
| 135 | "[gstack-memory-helpers] gitleaks not in PATH; secret scanning disabled. " + |
| 136 | "Run /setup-gbrain to install (or `brew install gitleaks`).\n" |
| 137 | ); |
| 138 | } |
| 139 | return _gitleaksAvailability; |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Scan a file for embedded secrets using gitleaks. Returns findings list |