* Find the gstack Chrome extension directory. * Checks: repo root /extension, global install, dev install.
()
| 285 | * Checks: repo root /extension, global install, dev install. |
| 286 | */ |
| 287 | private findExtensionPath(): string | null { |
| 288 | const fs = require('fs'); |
| 289 | const path = require('path'); |
| 290 | const candidates = [ |
| 291 | // Explicit override via env var (used by GStack Browser.app bundle) |
| 292 | process.env.BROWSE_EXTENSIONS_DIR || '', |
| 293 | // Relative to this source file (dev mode: browse/src/ -> ../../extension) |
| 294 | path.resolve(__dirname, '..', '..', 'extension'), |
| 295 | // Global gstack install |
| 296 | path.join(process.env.HOME || '', '.claude', 'skills', 'gstack', 'extension'), |
| 297 | // Git repo root (detected via BROWSE_STATE_FILE location) |
| 298 | (() => { |
| 299 | const stateFile = process.env.BROWSE_STATE_FILE || ''; |
| 300 | if (stateFile) { |
| 301 | const repoRoot = path.resolve(path.dirname(stateFile), '..'); |
| 302 | return path.join(repoRoot, '.claude', 'skills', 'gstack', 'extension'); |
| 303 | } |
| 304 | return ''; |
| 305 | })(), |
| 306 | ].filter(Boolean); |
| 307 | |
| 308 | for (const candidate of candidates) { |
| 309 | try { |
| 310 | if (fs.existsSync(path.join(candidate, 'manifest.json'))) { |
| 311 | return candidate; |
| 312 | } |
| 313 | } catch (err: any) { |
| 314 | if (err?.code !== 'ENOENT' && err?.code !== 'EACCES') throw err; |
| 315 | } |
| 316 | } |
| 317 | return null; |
| 318 | } |
| 319 | |
| 320 | /** |
| 321 | * Set the proxy config applied to chromium.launch() in launch() and |
no outgoing calls
no test coverage detected