Two bugs caused the brainstorm server to self-terminate within 60s:
1. ownerAlive() treated EPERM (permission denied) as "process dead".
When the owner PID belongs to a different user (Tailscale SSH,
system daemons), process.kill(pid, 0) throws EPERM — but the
process IS alive. Fixed: return e.code === 'EPERM'.
2. On WSL, the grandparent PID resolves to a short-lived subprocess
that exits before the first 60s lifecycle check. The PID is
genuinely dead (ESRCH), so the EPERM fix alone doesn't help.
Fixed: validate the owner PID at server startup — if it's already
dead, it was a bad resolution, so disable monitoring and rely on
the 30-minute idle timeout.
This also removes the Windows/MSYS2-specific OWNER_PID="" carve-out
from start-server.sh, since the server now handles invalid PIDs
generically at startup regardless of platform.
Tested on Linux (magic-kingdom) via Tailscale SSH:
- Root-owned owner PID (EPERM): server survives ✓
- Dead owner PID at startup (WSL sim): monitoring disabled, survives ✓
- Valid owner that dies: server shuts down within 60s ✓
Fixes#879
ownerAlive() treated EPERM (permission denied) the same as ESRCH
(process not found), causing the server to self-terminate within 60s
whenever the owner process ran as a different user. This affected WSL
(owner is a Windows process), Tailscale SSH, and any cross-user
scenario.
The fix: `return e.code === 'EPERM'` — if we get permission denied,
the process is alive; we just can't signal it.
Tested on Linux via Tailscale SSH with a root-owned grandparent PID:
- Server survives past the 60s lifecycle check (EPERM = alive)
- Server still shuts down when owner genuinely dies (ESRCH = dead)
Fixes#879
The session directory now contains two peers: content/ (HTML served to
the browser) and state/ (events, server-info, pid, log). Previously
all files shared a single directory, making server state and user
interaction data accessible over the /files/ HTTP route.
Also fixes stale test assertion ("Waiting for Claude" → "Waiting for
the agent").
Reported-By: 吉田仁
Metadata files (.server-info, .events, .server.pid, .server.log,
.server-stopped) were stored in the same directory served over HTTP,
making them accessible via the /files/ route. They now live in a .meta/
subdirectory that is not web-accessible.
Also fixes a stale test assertion ("Waiting for Claude" → "Waiting for
the agent").
Reported-By: 吉田仁
- Remove chunk-based plan review in favor of single whole-plan review
- Add Calibration sections to both reviewer prompts so only serious
issues block approval
- Reduce max review iterations from 5 to 3
- Streamline reviewer checklists (spec: 7→5, plan: 7→4 categories)
Resumed sessions already have injected context in their conversation
history. Re-firing the hook was redundant and could cause issues.
The hook now fires only on startup, clear, and compact.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The synchronous SessionStart hook blocked the TUI from entering raw
mode on Windows, freezing all keyboard input. The pure-bash
escape_for_json function is O(n^2) on Git Bash, taking 60+ seconds.
Running the hook async prevents the freeze while still injecting
superpowers context. Multiple users confirmed this workaround.
Fixes#404, #413, #414, #419
* fix: convert shell scripts from CRLF to LF line endings
Add .gitattributes to enforce LF line endings for shell scripts,
preventing bash errors like "/usr/bin/bash: line 1: : command not found"
when scripts are checked out on Windows with CRLF.
Fixes#317 (SessionStart hook fails due to CRLF line endings)
Files converted:
- hooks/session-start.sh
- lib/brainstorm-server/start-server.sh
- lib/brainstorm-server/stop-server.sh
- lib/brainstorm-server/wait-for-feedback.sh
- skills/systematic-debugging/find-polluter.sh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: update Windows hook execution for Claude Code 2.1.x
Claude Code 2.1.x changed the Windows execution model: it now auto-detects
.sh files in hook commands and prepends "bash " automatically. This broke
the polyglot wrapper because:
Before: "run-hook.cmd" session-start.sh (wrapper executes)
After: bash "run-hook.cmd" session-start.sh (bash can't run .cmd)
Changes:
- hooks.json now calls session-start.sh directly (Claude Code handles bash)
- Added deprecation comment to run-hook.cmd explaining the change
- Updated RELEASE-NOTES.md
Fixes#317, #313, #275, #292
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Breaking changes:
- OpenCode: Switched to native skills system (migration required)
Fixes:
- OpenCode: Fixed agent reset on session start (#226)
- OpenCode: Fixed Windows installation (#232)
- Claude Code: Fixed Windows hook execution for 2.1.x
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: convert shell scripts from CRLF to LF line endings
Add .gitattributes to enforce LF line endings for shell scripts,
preventing bash errors like "/usr/bin/bash: line 1: : command not found"
when scripts are checked out on Windows with CRLF.
Fixes#317 (SessionStart hook fails due to CRLF line endings)
Files converted:
- hooks/session-start.sh
- lib/brainstorm-server/start-server.sh
- lib/brainstorm-server/stop-server.sh
- lib/brainstorm-server/wait-for-feedback.sh
- skills/systematic-debugging/find-polluter.sh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: update Windows hook execution for Claude Code 2.1.x
Claude Code 2.1.x changed the Windows execution model: it now auto-detects
.sh files in hook commands and prepends "bash " automatically. This broke
the polyglot wrapper because:
Before: "run-hook.cmd" session-start.sh (wrapper executes)
After: bash "run-hook.cmd" session-start.sh (bash can't run .cmd)
Changes:
- hooks.json now calls session-start.sh directly (Claude Code handles bash)
- Added deprecation comment to run-hook.cmd explaining the change
- Updated RELEASE-NOTES.md
Fixes#317, #313, #275, #292
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix use_skill agent context (#290)
* fix: respect OPENCODE_CONFIG_DIR for personal skills lookup (#297)
* fix: respect OPENCODE_CONFIG_DIR for personal skills lookup
The plugin was hardcoded to look for personal skills in ~/.config/opencode/skills,
ignoring users who set OPENCODE_CONFIG_DIR to a custom path (e.g., for dotfiles management).
Now uses OPENCODE_CONFIG_DIR if set, falling back to the default path.
* fix: update help text to use dynamic paths
Use configDir and personalSkillsDir variables in help text so paths
are accurate when OPENCODE_CONFIG_DIR is set.
* fix: normalize OPENCODE_CONFIG_DIR before use
Handle edge cases where the env var might be:
- Empty or whitespace-only
- Using ~ for home directory (common in .env files)
- A relative path
Now trims, expands ~, and resolves to absolute path.
* feat(opencode): use native skills and fix agent reset bug (#226)
- Replace custom use_skill/find_skills tools with OpenCode's native skill tool
- Use experimental.chat.system.transform hook instead of session.prompt
(fixes#226 agent reset on first message)
- Symlink skills directory into ~/.config/opencode/skills/superpowers/
- Update installation docs with comprehensive Windows support:
- Command Prompt, PowerShell, and Git Bash instructions
- Proper symlink vs junction handling
- Reinstall safety with cleanup steps
- Verification commands for each shell
* Add OpenCode native skills changes to release notes
Documents:
- Breaking change: switch to native skill tool
- Fix for agent reset bug (#226)
- Fix for Windows installation (#232)
---------
Co-authored-by: Vinicius da Motta <viniciusmotta8@gmail.com>
Co-authored-by: oribi <oribarilan@gmail.com>
Addresses failure mode where Claude skips skill invocation even when
user explicitly requests it by name (e.g., "subagent-driven-development,
please").
Skill changes:
- "Check for skills" → "Invoke relevant or requested skills"
- "BEFORE ANY RESPONSE" → "BEFORE any response or action"
- Added reassurance that wrong skill invocations are okay
- New red flag: "I know what that means"
Tests:
- New test suite for explicit skill requests
- Single-turn and multi-turn scenarios with --continue
- Tests with haiku model and user CLAUDE.md
Added disable-model-invocation: true to /brainstorm, /execute-plan, and
/write-plan commands. Claude can still invoke the underlying skills
directly, but the slash commands are now restricted to manual user
invocation only.
Fixes pattern where Claude would invoke a skill then try to Read the
file separately. The Skill tool already provides the content.
- Add "How to Access Skills" section to using-superpowers
- Change "read the skill" → "invoke the skill"
- Commands now use fully qualified names (superpowers:brainstorming etc)
- Rewrite release notes centering new features (two-stage review,
debugging tools, test infrastructure)
- Bump version to 4.0.0 in plugin.json and marketplace.json
- Remove .claude/settings.local.json from tracking
- Add .claude/ to .gitignore
Fixed POSIX compatibility issue in hooks/run-hook.cmd that caused
"Bad substitution" errors on Ubuntu/Debian systems where /bin/sh is dash.
Changes:
- Replaced bash-specific ${BASH_SOURCE[0]:-$0} with POSIX-compliant $0
- Tested with both bash and sh (POSIX mode) on macOS
- Updated version to 3.6.2 in all required files
Fixes#141
Switch from chat.message hook to session.created event for injecting
the using-superpowers skill content. The new approach:
- Injects at session creation via session.prompt() with noReply: true
- Explicitly tells model the skill is already loaded to prevent
redundant use_skill calls
- Consolidates bootstrap generation into getBootstrapContent() helper
- Removes fallback pattern in favor of single implementation
Tested with 10 consecutive test runs and manual skill trigger validation.
- Update session-start hook to clarify that using-superpowers content is provided directly
- Add explicit guidance to use Skill tool only for other skills
- Prevents confusing loop where agents execute using-superpowers manually
- Reduces overhead and improves user experience
Fixes redundant skill execution in bootstrap workflow.