mirror of
https://github.com/obra/superpowers.git
synced 2026-06-11 13:19:05 +08:00
feat(brainstorm-server): opt-in auto-open of the browser on the first screen
When the user approves the visual companion, open their browser automatically the first time a screen is actually ready to show — rather than at startup (just the waiting page) or making them open the URL by hand. Opt-in and gated on approval: off unless BRAINSTORM_OPEN is set (start-server.sh --open, which the agent passes only after the user agrees to use the companion). Even then it fires once, and is skipped if a browser is already connected, on a non-loopback/remote bind, or when headless. Launcher is the platform default (open / xdg-open / WSL cmd.exe) or BRAINSTORM_OPEN_CMD; best-effort, never fatal. lifecycle.test.js: opens once on the first screen when approved; does NOT open without approval. Closes #755 Refs #759
This commit is contained in:
@@ -267,6 +267,27 @@ function broadcast(msg) {
|
||||
}
|
||||
}
|
||||
|
||||
// Best-effort: open the user's browser the first time a screen is actually ready
|
||||
// to show. Skips when disabled, on a non-loopback (remote) bind, or when a
|
||||
// browser is already connected. Override the launcher with BRAINSTORM_OPEN_CMD.
|
||||
let browserOpened = false;
|
||||
function maybeOpenBrowser() {
|
||||
if (browserOpened) return;
|
||||
browserOpened = true;
|
||||
if (!process.env.BRAINSTORM_OPEN) return; // opt-in: only after the user approves the companion
|
||||
if (HOST !== '127.0.0.1' && HOST !== 'localhost') return;
|
||||
if (clients.size > 0) return; // the user already opened it
|
||||
const url = 'http://' + URL_HOST + ':' + PORT;
|
||||
let cmd = process.env.BRAINSTORM_OPEN_CMD;
|
||||
if (!cmd) {
|
||||
if (process.platform === 'darwin') cmd = 'open';
|
||||
else if (/microsoft/i.test(require('os').release())) cmd = 'cmd.exe /c start ""'; // WSL → Windows browser
|
||||
else if (process.env.DISPLAY || process.env.WAYLAND_DISPLAY) cmd = 'xdg-open';
|
||||
else return; // headless: nothing to open
|
||||
}
|
||||
try { require('child_process').exec(cmd + ' ' + JSON.stringify(url), () => {}); } catch (e) { /* best effort */ }
|
||||
}
|
||||
|
||||
// ========== Activity Tracking ==========
|
||||
|
||||
// Idle timeout: shut down after this long with no activity. Default 4 hours;
|
||||
@@ -323,6 +344,7 @@ function startServer() {
|
||||
const eventsFile = path.join(STATE_DIR, 'events');
|
||||
if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile);
|
||||
console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
|
||||
maybeOpenBrowser();
|
||||
} else {
|
||||
console.log(JSON.stringify({ type: 'screen-updated', file: filePath }));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
# Use 0.0.0.0 in remote/containerized environments.
|
||||
# --url-host <host> Hostname shown in returned URL JSON.
|
||||
# --idle-timeout-minutes <n> Shut down after n minutes idle (default 240 = 4h).
|
||||
# --open Auto-open the browser on the first screen (use only
|
||||
# after the user approves the visual companion).
|
||||
# --foreground Run server in the current terminal (no backgrounding).
|
||||
# --background Force background mode (overrides Codex auto-foreground).
|
||||
|
||||
@@ -42,6 +44,10 @@ while [[ $# -gt 0 ]]; do
|
||||
IDLE_TIMEOUT_MINUTES="$2"
|
||||
shift 2
|
||||
;;
|
||||
--open)
|
||||
export BRAINSTORM_OPEN=1
|
||||
shift
|
||||
;;
|
||||
--foreground|--no-daemon)
|
||||
FOREGROUND="true"
|
||||
shift
|
||||
|
||||
Reference in New Issue
Block a user