mirror of
https://github.com/obra/superpowers.git
synced 2026-08-29 18:09:27 +00:00
b36e0829c6d0140e93cfef2ca599b1b07d4a7797
83 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b36e0829c6 |
Release v6.3.0: Devin CLI and Hermes Agent support, brainstorming three-path router, SDD/Codex efficiency fixes (#2125)
* fix(codex): suppress SessionStart hook auto-discovery with empty hooks object
Codex auto-discovers a plugin's hooks/hooks.json whenever the Codex
manifest has no `hooks` field: load_plugin_hooks falls back to a
hardcoded DEFAULT_HOOKS_CONFIG_FILE = "hooks/hooks.json" and registers
it. hooks/hooks.json is the Claude Code SessionStart hook, it is tracked
in this repo, and the Codex marketplace installs the whole repo root
(source url "./"), so the fallback re-registered the SessionStart hook
and its install-time trust prompt on Codex.
Removing the Codex hook file and the manifest `hooks` pointer (commit
"Remove Codex hooks") did not disable the hook on Codex — it removed the
explicit declaration that was overriding the fallback, so the fallback
took over and found the Claude hooks/hooks.json.
Declare an empty inline hooks object ({}) in .codex-plugin/plugin.json.
It parses as an empty inline hook set and stops Codex reaching the
auto-discovery fallback. An absent field, an empty array ([]), and an
empty inline list all collapse back to the fallback, so the value must
be exactly {}.
Update the test to assert the manifest declares hooks: {} (and that
hooks/hooks.json exists, which is what makes the declaration necessary),
replacing the prior assertion that the field was absent — which passed
while the hook was still being auto-discovered.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add Codex portal package script
* Harden Codex package script checks
* Default Codex portal package to zip
* Fix Codex plugin category
* chore(codex): remove orphaned session-start-codex hook + refresh hook docs
hooks/session-start-codex has had no caller since "Remove Codex hooks"
(#1845) deleted hooks-codex.json and its manifest registration; the
Codex manifest now declares an empty hooks object so Codex registers no
session-start hook at all. The script is Codex-specific dead code —
nothing executes it on Codex or any other harness.
- Delete hooks/session-start-codex.
- tests/hooks/test-session-start.sh: drop the two Codex cases that are
redundant with the generic session-start tests (nested-format and the
legacy-warning omission are already covered by the Claude Code cases).
Re-point the "wrapper dispatches" case to the live `session-start`
script so run-hook.cmd dispatch coverage — used by Claude Code and
Cursor in production — is preserved rather than lost.
- docs/porting-to-a-new-harness.md: Codex is no longer a Shape A
(shell-hook) harness, so re-anchor that worked example to Cursor (a
live shell-hook harness that demonstrates the same per-harness field,
schema, and matcher variance) and mark Codex as native skill discovery
with no session-start hook. Clears the references to the deleted
hooks-codex.json.
- docs/windows/polyglot-hooks.md: the "check hooks-codex.json" pointer
referenced a file deleted in #1845; re-point to hooks-cursor.json.
RELEASE-NOTES.md keeps its historical mention of hooks-codex.json (it
accurately records what that release did). The tests/codex-plugin-sync
fixtures build their own synthetic session-start-codex and test the sync
mechanism generically, so they are intentionally left as-is.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: re-anchor Shape A examples away from Codex
* Strip hooks from Codex portal package
* Preserve hooks in Codex package manifest
* Release v6.1.1: fix Codex SessionStart hook re-registration, add Codex portal packaging
* Revert "Remove Gemini CLI support"
This reverts commit
|
||
|
|
05d90ac592 |
refactor(skills): fold brainstorming Key Principles into points of use
Five of six principles restated the Checklist and Process sections verbatim-in-spirit. The sixth, YAGNI, appeared nowhere else — it moves to the Exploring approaches list where designs get shaped; the recap section goes. |
||
|
|
1d4c8d2aaf |
Revert "Remove Gemini CLI support"
This reverts commit
|
||
|
|
711d895ce7 |
Remove Gemini CLI support
Google EOLed the Gemini CLI on 2026-06-18; the extension can no longer be installed or updated. Remove Gemini from the install docs, the subagent-capable platform lists, and the eval-harness description, and delete its tool-mapping reference. |
||
|
|
29c0b1b7db | fix: read Codex plugin version from manifest (PRI-2240) | ||
|
|
b3ee712d3a | Add visual companion Prime Radiant branding | ||
|
|
3a907d6a0a | Fix companion stop metadata and token permissions | ||
|
|
1c80914052 | Harden Windows browser launcher | ||
|
|
2a8479b21d | Fix Windows lifecycle validation | ||
|
|
fd9972a4bd | Align visual companion docs with shipped scope | ||
|
|
6bc49f0183 | Harden companion stop ownership proof | ||
|
|
8f2525a803 | Isolate companion fallback tokens | ||
|
|
0410679757 | Harden root screen containment | ||
|
|
69270c9007 | Harden companion Windows lifecycle coverage | ||
|
|
b17d54f839 | Harden brainstorm companion auth regressions | ||
|
|
7fbae0252f |
fix(brainstorm-server): fix auth-integration bugs from full-branch review
A second adversarial review of the merged branch found that combining the session-key auth with the feature work created real bugs the (vacuous) tests missed: - [Critical] GET /files/ (empty name) resolved to CONTENT_DIR and crashed the process with uncaught EISDIR — newly reachable because the query-stripping refactor turns /files/?key=... into /files/. Reject non-regular-file names. - [High] --open opened a KEYLESS url, which the auth gate 403s — the headline feature landed on the error page. Open the keyed url. - [High] Same-port restart regenerated the token (port persisted, token not), so the open tab's old cookie 403'd and never reconnected — contradicting the documented promise. Persist the token (BRAINSTORM_TOKEN_FILE / .last-token) alongside the port. - [Medium] Token sat in world-readable server-info/server.log (0644 in /tmp). umask 077 in start-server.sh + mode 0600 on server-info/.last-token. - [Medium] touchActivity() ran before the auth check, so unauthenticated requests defeated the idle timeout. Count activity only after authorization. - [Low] COOKIE_NAME embedded the pre-fallback port; derive it from the actual bound port (also prevents a cross-server cookie-jar collision on fallback). Tests added/strengthened (previously passed vacuously): /files/ no-crash; the auto-open url carries the key and is reachable (200); restart reuses the same key not just the port; unauthenticated requests don't reset the idle clock. Full suite green (ws-protocol 32, helper 12, auth 13, server 29, lifecycle 8, stop-server 4); restart smoke confirms same port+key and old URL -> 200. |
||
|
|
cb5bb885fd |
feat(brainstorm-server): gate every endpoint behind a per-session key
The companion server is reachable by any local browser tab (default loopback bind) and by any host that can route to it (remote --host bind). It served screens, files, and accepted event-injecting WebSocket connections with no authentication, so a malicious browser tab or a direct remote client could read brainstorm content or inject events that the agent reads as the user's input (prompt injection into a live session). Generate a per-session secret token, carry it in the served URL as ?key=, and mirror it into an HttpOnly SameSite=Strict per-port cookie on first load so same-origin subresources and the WebSocket handshake authenticate automatically. Every HTTP request and WebSocket upgrade now requires a valid key (query or cookie, constant-time compared); unauthenticated requests get a friendly 403 explaining they need the full URL. A secret authenticates the client uniformly across loopback, tunnel, and remote binds and defeats DNS rebinding, which a Host/Origin allowlist cannot. Also guard handleMessage against a null JSON payload that crashed the process. Tests: new auth.test.js (13 cases) covering the key on /, /files/*, and WS plus cookie bootstrap and the null-payload guard; server.test.js threads the key; ws-protocol.test.js + auth.test.js wired into npm test. Closes #1014 Refs #1110, #1553, #1504 |
||
|
|
7c805f34d2 |
fix(brainstorm-server): tie stop-server PID check to the session's port
The node+server.cjs command match (from the adversarial review) still matched any unrelated node process running a file named server.cjs. When we recorded the bound port (state/server-info) and lsof is available, additionally require the PID to be the process actually LISTENING on this session's port — which rules out a different project's server.cjs / editor task runner that recycled the stale PID. Falls back to the command match when the port or lsof isn't available. Test: a 'node server.cjs' process not listening on the recorded port is spared. Refs #1703 |
||
|
|
fb08947ded |
fix(brainstorm-server): address adversarial review findings
From a two-reviewer adversarial pass: - [High] EADDRINUSE fallback clobbered the shared .last-port: onListen wrote the bound port unconditionally, so a fallback to a random port overwrote the preferred port another live session still owns — stranding that session's open tab forever. Now persist only when we bound the preferred port (not on fallback). The fallback test now asserts .last-port integrity (teeth-verified). - [Medium] maybeOpenBrowser ran the URL through a shell (exec + JSON.stringify), which does NOT neutralize $(...) in a url-host. Platform launchers now use execFile with the URL as an argv element (no shell). The operator-set BRAINSTORM_OPEN_CMD path stays shell-based (trusted input). - [Medium] --open was a silent no-op on native Windows (no win32 branch). Added. - [Medium] helper.js reconnect/status/tombstone had only substring-grep tests. Added behavioral tests driving the state machine against a mocked browser: Reconnecting+backoff (500->1000->2000), tombstone after the grace period, and reload-on-recovery. - [Low] status pill showed a false 'Connected' before the socket opened; now starts 'Connecting…' until onopen. Not changed (flagged): stop-server.sh's PID-ownership check still matches any 'node ... server.cjs' (narrow residual — a recycled PID onto an unrelated node server.cjs); robust fix needs fragile cross-platform process introspection. |
||
|
|
5a0f895387 |
feat(brainstorming): offer the visual companion just-in-time; harden lifecycle guidance
Move the companion consent from an upfront, anticipatory offer to the first moment a question would genuinely be clearer shown than told. If no visual question ever arises, it's never offered. On approval the agent starts the server with --open, so the user's browser opens to the first screen — the pop is tied to that approval, never unsolicited. Also hardens visual-companion.md: confirming the server is alive (server-info present, server-stopped absent) before referring to the URL is now a required step; restart with the same --project-dir reuses the port so the open tab reconnects on its own (paused overlay while down); idle default corrected to 4h. NOTE: SKILL.md is behavior-shaping content — this flow change should be eval-tested (writing-skills adversarial pressure test) before merge. Refs #1237, #1037 |
||
|
|
463dfb7fd4 |
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 |
||
|
|
dd9fcc21ee |
feat(brainstorm-server): reuse the same port on session restart
When the companion idle-shuts-down and the agent restarts it, a fresh random port meant the user's open browser tab pointed at a dead URL. Persist the bound port per project and prefer it on the next start, so the restarted server comes up on the same port and the open tab's reconnect just works. - start-server.sh exports BRAINSTORM_PORT_FILE=<project>/.superpowers/brainstorm/ .last-port for project sessions (not /tmp). - server.cjs prefers an explicit BRAINSTORM_PORT, else the recorded port, else random; writes the actually-bound port back; and on EADDRINUSE (preferred port still in use) falls back to a random port once instead of crashing. lifecycle.test.js: restart reuses the recorded port; a taken preferred port falls back to a random one without crashing. Refs #1237 |
||
|
|
36ac3e1336 |
feat(brainstorm-companion): resilient reconnect, live status, paused overlay
The injected client reconnected on a fixed 1s timer with no feedback: if the laptop slept or the server restarted, the page showed 'Connected' over a dead socket and silently queued events. And when the server stopped, the user got a bare connection-refused with no explanation. helper.js now: - reconnects with exponential backoff (500ms, doubling, capped at 30s; reset on open), with an onerror->close handler, nulls the socket on close, and clears a pending timer before scheduling another; - drives the frame status pill Connected/Reconnecting/Disconnected via a --status-color custom property (frame-template.html); - after ~15s disconnected, shows a self-styled 'Companion paused' overlay (tombstone) explaining the companion stopped and will reconnect automatically; - on recovery from a tombstoned outage (e.g. server restarted on the same port) reloads to pick up the restarted server's current screen. The reconnect-backoff is an exported pure function; helper.test.js unit-tests it (doubling + cap progression) and asserts the status/tombstone/reconnect wiring. DOM behaviour is verified live. Refs #856, #1237 |
||
|
|
56757f6877 |
feat(brainstorm-server): 4h configurable idle timeout; close WS on shutdown
The companion shut down after only 30 minutes idle — too short for real brainstorming, where a single question can sit far longer. And shutdown() never closed upgraded WebSocket sockets, so an open browser connection could keep the Node process alive after it was supposed to exit. - Default idle timeout raised to 4 hours, configurable via BRAINSTORM_IDLE_TIMEOUT_MS and start-server.sh --idle-timeout-minutes (validated positive integer). - Reported as idle_timeout_ms in the server-started JSON / server-info. - shutdown() now destroys all client sockets so the process exits even with an open WebSocket. - Watchdog check interval is configurable (BRAINSTORM_LIFECYCLE_CHECK_MS, default 60s) so the lifecycle can be tested without minute-long waits. Adds lifecycle.test.js (configured timeout reported; idle shutdown exits despite an open WS — teeth-verified; the start-server flag). Wires ws-protocol, lifecycle, and stop-server suites into npm test. Closes #1237 Refs #1689 |
||
|
|
5ddce063df |
fix(brainstorm-server): verify PID ownership before stopping
stop-server.sh read server.pid and SIGKILL'd that PID with no checks. After a
reboot or PID wraparound the pid file can point at an unrelated, live process —
which we would then kill.
Verify the PID is actually our server (a running 'node ... server.cjs') before
signalling it. If ownership can't be proven, fail closed: remove the stale pid
file and report {status: stale_pid} without killing anything. Real servers still
stop ({status: stopped}); a missing pid file still reports not_running.
Adds stop-server.test.sh covering: an unrelated reused PID is left alone, a real
server is stopped, and a missing pid file.
Refs #1703
|
||
|
|
2b108b7dc2 |
fix(brainstorm-server): ignore macOS resource-fork dotfiles
On macOS (and ExFAT/SMB volumes) the OS writes ._<name>.html sidecar files holding binary resource-fork metadata. These end with .html, so they passed the content filter and could be picked as the newest screen — serving binary garbage to the browser instead of the mockup — or fetched via /files/. Skip dotfiles (leading '.') at all four sites that list or serve content: getNewestScreen, the /files/ endpoint, the known-files seed, and the fs.watch handler. Tests cover serving (/ and /files/) and the watch path (a ._ file must not trigger a reload). Refs #950 |
||
|
|
d9d3d99245 | fix(brainstorming): cap websocket frame payloads | ||
|
|
48696e6519 |
fix: foreground mode saves node PID and clears OWNER_PID on Windows/MSYS2
Verified on real Windows Git Bash: lifecycle test passed 12/12, manual start/stop released the port, and no brainstorm node processes remained. |
||
|
|
8ca7d218d0 |
Revert "Make visual-companion.md script paths skill-rooted, not plugin-rooted"
This reverts commit
|
||
|
|
a318a5f621 |
Make visual-companion.md script paths skill-rooted, not plugin-rooted
Issue #1134: agents reading visual-companion.md see bare commands like `scripts/start-server.sh`, correctly identify the plugin install directory, then look for `<plugin>/scripts/start-server.sh` instead of `<plugin>/skills/brainstorming/scripts/start-server.sh`. The file doesn't exist at the plugin-rooted path, so the agent concludes the visual companion isn't available and falls back to text-only brainstorming. Multiple independent reproductions in the issue thread, plus one user's agent self-reported: "I assumed the scripts folder was in the root directory of the plugin, it didn't realize it could have been talking about the skill folder itself." Change all `scripts/<file>` references in visual-companion.md to `skills/brainstorming/scripts/<file>`. Agents that correctly identify the plugin root will now join to the right path. Closes #1134. |
||
|
|
d7f47d350a |
Phase E: action-language tool vocabulary
Replace Claude-Code-specific tool names in skill prose, prompt
templates, and OpenCode-facing docs with action-language descriptions
that resolve to each runtime's native tool via the per-platform refs.
Changes by category:
- Prose mentions ("Use TodoWrite to track...", "Use Task tool with
general-purpose type") → action language ("Track each item as a
todo", "Dispatch a general-purpose subagent")
- Prompt template headers (6 files): "Task tool (general-purpose):"
→ "Subagent (general-purpose):" — preserves the type information
without naming Claude Code's specific dispatch tool
- DOT flowchart node labels: "Invoke Skill tool" → "Invoke the
skill"; "Create TodoWrite todo per item" → "Create a todo per
item"
- OpenCode INSTALL.md and docs/README.opencode.md: replace the old
"TodoWrite → todowrite, Task → @mention" mapping (which both
taught a vocabulary skills no longer use AND was wrong about
@mention being a real OpenCode syntax) with an action-language
mapping verified against the installed OpenCode CLI's tool
inventory.
The platform-tools refs landed in Phase B already document each
runtime's resolution; skills now speak in the actions those refs
map. Tool names that genuinely belong only in the per-platform
dispatch section ("In Claude Code: Use the `Skill` tool") and the
Claude-Code-specific Bash run_in_background flag note in
visual-companion remain — those are intentional carve-outs.
|
||
|
|
6ec8686477 |
Phase D: cross-runtime tweaks (visual-companion, executing-plans, test)
Misc platform/runtime statements and adjacencies that don't fit the prose, config-ref, README-ordering, or tool-vocabulary buckets: - visual-companion frame template: rename CSS/HTML id #claude-content → #frame-content. The id is purely styling — nothing external references it. The brainstorm-server test that asserted the old string is updated in lockstep. - visual-companion launch instructions: add a Copilot CLI section alongside Claude Code, Codex, and Gemini CLI; combine the Claude Code (macOS / Linux) and (Windows) sections so heading style matches the other (non-OS-qualified) platforms. - visual-companion: "Use Write tool" → "Use your file-creation tool" for the cat/heredoc warning. The prohibition is what's load- bearing, not the tool name. - executing-plans/SKILL.md: list all subagent-capable runtimes (Claude Code, Codex CLI, Codex App, Copilot CLI, Gemini CLI) and point at the per-platform tool refs as the source of truth. - executing-plans/SKILL.md: relative path "using-superpowers/ references/" → "../using-superpowers/references/" to resolve correctly from the executing-plans/ directory. No bundled spec doc here — Phase D was scope-extension work that took place across rounds, with no standalone spec authored. |
||
|
|
9f04f06351 |
Fix owner-PID lifecycle monitoring for cross-platform reliability
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 |
||
|
|
f076bd3431 |
Fix owner-PID false positive when owner runs as different user
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 |
||
|
|
9e3ed213a0 |
Separate brainstorm server content and state into peer directories
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: 吉田仁
|
||
|
|
9e6e077d33 |
Revert "Move brainstorm server metadata to .meta/ subdirectory"
This reverts commit
|
||
|
|
151cfb16a0 |
Move brainstorm server metadata to .meta/ subdirectory
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: 吉田仁
|
||
|
|
3f80f1c769 |
Reapply "Replace subagent review loops with lightweight inline self-review"
This reverts commit
|
||
|
|
4ae1a3d6a6 |
Revert "Replace subagent review loops with lightweight inline self-review"
This reverts commit
|
||
|
|
e6221a48c5 |
Replace subagent review loops with lightweight inline self-review
The subagent review loop (dispatching a fresh agent to review plans/specs) doubled execution time (~25 min overhead) without measurably improving plan quality. Regression testing across 5 versions (v3.6.0 through v5.0.4) with 5 trials each showed identical plan sizes, task counts, and quality scores regardless of whether the review loop ran. Changes: - writing-plans: Replace subagent Plan Review Loop with inline Self-Review checklist (spec coverage, placeholder scan, type consistency) - writing-plans: Add explicit "No Placeholders" section listing plan failures (TBD, vague descriptions, undefined references, "similar to Task N") - brainstorming: Replace subagent Spec Review Loop with inline Spec Self-Review (placeholder scan, internal consistency, scope check, ambiguity check) - Both skills now use "look at it with fresh eyes" framing Testing: 5 trials with the new skill show self-review catches 3-5 real bugs per run (spawn positions, API mismatches, seed bugs, grid indexing) in ~30s instead of ~25 min. Remaining defects are comparable to the subagent approach. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3128a2c3cd | fix : resolve ESM/CommonJS module confict in brainstorming server | ||
|
|
f34ee479b7 |
fix: Windows brainstorm server lifecycle, restore execution choice
- Skip OWNER_PID monitoring on Windows/MSYS2 where the PID namespace is invisible to Node.js, preventing server self-termination after 60s (#770) - Document run_in_background: true for Claude Code on Windows (#767) - Restore user choice between subagent-driven and inline execution after plan writing; subagent-driven is recommended but no longer mandatory - Add Windows lifecycle test script verified on Windows 11 VM - Note #723 (stop-server.sh reliability) as already fixed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
61a64d7098 | fix: verify server actually stopped in stop-server.sh | ||
|
|
a4c48714bc | Use generic "the agent" instead of "Claude" in brainstorm server | ||
|
|
2c6a8a352d |
Tone down review loops: single-pass plan review, raise issue bar
- 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) |
||
|
|
addfe8511a |
fix: use portable shebang #!/usr/bin/env bash in all shell scripts
Replace #!/bin/bash with #!/usr/bin/env bash in 13 scripts. The hardcoded path fails on NixOS, FreeBSD, and macOS with Homebrew bash. #!/usr/bin/env bash is the portable POSIX-friendly alternative. Tested on Linux and Windows (Git Bash + CMD). macOS is the primary beneficiary since Homebrew installs bash to /opt/homebrew/bin/bash. Based on #700, closes #700. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
c6a2b1b576 |
fix: auto-foreground brainstorm server on Windows/Git Bash
Windows/Git Bash reaps nohup background processes, causing the brainstorm server to die silently after launch. Auto-detect Windows via OSTYPE (msys/cygwin/mingw) and MSYSTEM env vars, switching to foreground mode automatically. Tested on Windows 11 from CMD, PowerShell, and Git Bash — all route through Git Bash and hit the same issue. Based on #740, fixes #737. Also adds CHANGELOG.md documenting the fix and a known OWNER_PID/WINPID mismatch on the main branch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
9ccce3bf07 |
Add context isolation principle to all delegation skills
Subagents should never inherit the parent session's context or history. The dispatcher constructs exactly what each subagent needs, keeping both sides focused: the subagent on its task, the controller on coordination. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
b484bae134 |
Fix owner PID tracking: resolve grandparent to get actual harness PID
$PPID inside start-server.sh is the ephemeral shell the harness spawns to run the script — it dies immediately when the script exits, causing the server to shut down after ~60s. Now resolves grandparent PID via `ps -o ppid= -p $PPID` to get the actual harness process (e.g. claude). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
ec99b7c4a4 |
Exit server when owner process dies (harness-agnostic cleanup)
start-server.sh passes $PPID as BRAINSTORM_OWNER_PID to the server. The server checks every 60s if the owner process is still alive (kill -0). If it's gone, the server shuts down immediately — deletes .server-info, writes .server-stopped, exits cleanly. Works across all harnesses (CC, Codex, Gemini CLI) since it tracks the shell process that launched the script, which dies when the harness dies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |