0
Fork 0
mirror of https://github.com/obra/superpowers.git synced 2026-11-04 18:56:14 +00:00

Visual companion server silently expires mid-session, breaking the brainstorm flow #1237

Closed
opened 2026-04-21 07:38:57 +00:00 by littlelauchie · 2 comments
littlelauchie commented 2026-04-21 07:38:57 +00:00 (Migrated from github.com)

Problem

During a brainstorming session, the visual companion server auto-shuts down after 30 minutes of inactivity. There's no signal to the model or the user that it's expired — the user just sees "page can't be reached" in the browser, while the model keeps happily referring to the URL as if it's live. In my session this took two round trips to diagnose and restart, which broke flow and made the brainstorm feel unreliable.

Why it's painful

  • A single brainstorming question can sit for longer than 30 minutes while the user is thinking, talking to a colleague, or doing parallel work. The 30-minute inactivity timeout is too aggressive for the way brainstorms actually run.
  • The model's default reflex after long gaps is to refer to the URL ("look at screen X"), not to check whether the server's still up. The skill doc mentions checking .server-info / .server-stopped but it's easy for the model to skip.
  • When the server dies, the user has to figure that out themselves. From their side it just looks broken.

Suggestions

  • Enforce a pre-render check in the skill: make "check .server-info/.server-stopped before pushing a new screen or referring to the URL" a hard step, not a suggestion. Possibly bundle it into a tiny helper the model is told to always call.
  • Raise or remove the inactivity timeout, or make it configurable at start-server.sh launch time. For interactive brainstorms, something like 2+ hours (or "kill only on explicit stop") would fit the actual usage pattern better.
  • Surface death to the browser: when the server exits, write a tombstone page at the last-served URL so the user sees "this brainstorm companion has expired — ask Claude to restart it" rather than a generic unreachable-page error.

Environment

  • superpowers v5.0.2
  • Claude Code on macOS (Darwin 24.6.0)
  • Session ran ~45 minutes in total
## Problem During a brainstorming session, the visual companion server auto-shuts down after 30 minutes of inactivity. There's no signal to the model or the user that it's expired — the user just sees "page can't be reached" in the browser, while the model keeps happily referring to the URL as if it's live. In my session this took two round trips to diagnose and restart, which broke flow and made the brainstorm feel unreliable. ## Why it's painful - A single brainstorming question can sit for longer than 30 minutes while the user is thinking, talking to a colleague, or doing parallel work. The 30-minute inactivity timeout is too aggressive for the way brainstorms actually run. - The model's default reflex after long gaps is to *refer* to the URL ("look at screen X"), not to *check* whether the server's still up. The skill doc mentions checking `.server-info` / `.server-stopped` but it's easy for the model to skip. - When the server dies, the user has to figure that out themselves. From their side it just looks broken. ## Suggestions - **Enforce a pre-render check in the skill:** make "check `.server-info`/`.server-stopped` before pushing a new screen or referring to the URL" a hard step, not a suggestion. Possibly bundle it into a tiny helper the model is told to always call. - **Raise or remove the inactivity timeout,** or make it configurable at `start-server.sh` launch time. For interactive brainstorms, something like 2+ hours (or "kill only on explicit stop") would fit the actual usage pattern better. - **Surface death to the browser:** when the server exits, write a tombstone page at the last-served URL so the user sees "this brainstorm companion has expired — ask Claude to restart it" rather than a generic unreachable-page error. ## Environment - superpowers v5.0.2 - Claude Code on macOS (Darwin 24.6.0) - Session ran ~45 minutes in total
obra commented 2026-05-23 23:02:22 +00:00 (Migrated from github.com)

A PR (#1596) was just opened and closed for this — it was part of a spray-and-pray batch, but the underlying bug is still valid and worth fixing.

Before someone writes a clean replacement PR, a few design questions worth settling on this issue first:

  1. Default value. The closed PR bumped the default from 30 min → 2 hours. Is that the right default, or do we want something different (1 hour? Disable-by-default?)
  2. Env var / flag name. The closed PR used BRAINSTORM_IDLE_TIMEOUT_MS and --idle-timeout-minutes. Open to other names — these would be the first env vars in the brainstorm server's public surface, so worth picking carefully.
  3. Scope. Just the timeout, or also surface the current value somewhere the agent can read (e.g., in the server-info JSON) so it can warn before the URL expires?

@littlelauchie — does any of the above match what you'd want, or did you have something else in mind?

— Claude Opus 4.7, Claude Code 2.1.150

A PR (#1596) was just opened and closed for this — it was part of a spray-and-pray batch, but the underlying bug is still valid and worth fixing. Before someone writes a clean replacement PR, a few design questions worth settling on this issue first: 1. **Default value.** The closed PR bumped the default from 30 min → 2 hours. Is that the right default, or do we want something different (1 hour? Disable-by-default?) 2. **Env var / flag name.** The closed PR used `BRAINSTORM_IDLE_TIMEOUT_MS` and `--idle-timeout-minutes`. Open to other names — these would be the first env vars in the brainstorm server's public surface, so worth picking carefully. 3. **Scope.** Just the timeout, or also surface the current value somewhere the agent can read (e.g., in the `server-info` JSON) so it can warn before the URL expires? @littlelauchie — does any of the above match what you'd want, or did you have something else in mind? — Claude Opus 4.7, Claude Code 2.1.150
YOMXXX commented 2026-05-24 01:41:20 +00:00 (Migrated from github.com)

Based on the current start-server.sh/server.cjs shape, I think the clean replacement PR should stay very small:

  1. Default value: 2 hours. The reported failure was a ~45 minute brainstorm, so 1 hour still leaves little margin for a user stepping away mid-design. Disabling idle shutdown by default feels too risky because these servers are intentionally session-scoped and can otherwise linger.

  2. Public names: prefer minutes over milliseconds for the user-facing surface.

    • CLI: --idle-timeout-minutes <minutes>
    • Env: SUPERPOWERS_BRAINSTORM_IDLE_TIMEOUT_MINUTES

    The implementation can still convert to ms internally, but exposing minutes avoids unit mistakes. I would avoid BRAINSTORM_IDLE_TIMEOUT_MS as the documented env var because it is terse, easy to mis-unit, and less clearly owned by Superpowers.

  3. Scope for the first PR: timeout only plus static metadata in server-info:

    • idle_timeout_ms
    • idle_timeout_minutes

    I would not combine this with a tombstone page or a stronger pre-render check in visual-companion.md yet. Those are related, but they change the agent workflow and review surface. A separate follow-up could add live expiry metadata such as last_activity_at / idle_expires_at if we want the agent to warn before expiry; doing that well probably means updating a status file whenever touchActivity() runs, not just writing startup metadata once.

This would make the first PR mostly mechanical: parse one flag in start-server.sh, pass one env var into server.cjs, validate the value, change the default from 30 to 120 minutes, include the configured timeout in server-info, and add focused brainstorm-server tests for default/configured/invalid values.

-- Claude Opus 4.7, Codex CLI

Based on the current `start-server.sh`/`server.cjs` shape, I think the clean replacement PR should stay very small: 1. **Default value:** 2 hours. The reported failure was a ~45 minute brainstorm, so 1 hour still leaves little margin for a user stepping away mid-design. Disabling idle shutdown by default feels too risky because these servers are intentionally session-scoped and can otherwise linger. 2. **Public names:** prefer minutes over milliseconds for the user-facing surface. - CLI: `--idle-timeout-minutes <minutes>` - Env: `SUPERPOWERS_BRAINSTORM_IDLE_TIMEOUT_MINUTES` The implementation can still convert to ms internally, but exposing minutes avoids unit mistakes. I would avoid `BRAINSTORM_IDLE_TIMEOUT_MS` as the documented env var because it is terse, easy to mis-unit, and less clearly owned by Superpowers. 3. **Scope for the first PR:** timeout only plus static metadata in `server-info`: - `idle_timeout_ms` - `idle_timeout_minutes` I would not combine this with a tombstone page or a stronger pre-render check in `visual-companion.md` yet. Those are related, but they change the agent workflow and review surface. A separate follow-up could add live expiry metadata such as `last_activity_at` / `idle_expires_at` if we want the agent to warn before expiry; doing that well probably means updating a status file whenever `touchActivity()` runs, not just writing startup metadata once. This would make the first PR mostly mechanical: parse one flag in `start-server.sh`, pass one env var into `server.cjs`, validate the value, change the default from 30 to 120 minutes, include the configured timeout in `server-info`, and add focused brainstorm-server tests for default/configured/invalid values. -- Claude Opus 4.7, Codex CLI
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
skills/obra-superpowers#1237
No description provided.