Repository: obra/superpowers Branch: main Commit: 8ea39819eed7 Files: 135 Total size: 666.9 KB Directory structure: gitextract_hdkcvdqd/ ├── .claude-plugin/ │ ├── marketplace.json │ └── plugin.json ├── .codex/ │ └── INSTALL.md ├── .cursor-plugin/ │ └── plugin.json ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── config.yml │ │ ├── feature_request.md │ │ └── platform_support.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .opencode/ │ ├── INSTALL.md │ └── plugins/ │ └── superpowers.js ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── GEMINI.md ├── LICENSE ├── README.md ├── RELEASE-NOTES.md ├── agents/ │ └── code-reviewer.md ├── commands/ │ ├── brainstorm.md │ ├── execute-plan.md │ └── write-plan.md ├── docs/ │ ├── README.codex.md │ ├── README.opencode.md │ ├── plans/ │ │ ├── 2025-11-22-opencode-support-design.md │ │ ├── 2025-11-22-opencode-support-implementation.md │ │ ├── 2025-11-28-skills-improvements-from-user-feedback.md │ │ └── 2026-01-17-visual-brainstorming.md │ ├── superpowers/ │ │ ├── plans/ │ │ │ ├── 2026-01-22-document-review-system.md │ │ │ ├── 2026-02-19-visual-brainstorming-refactor.md │ │ │ └── 2026-03-11-zero-dep-brainstorm-server.md │ │ └── specs/ │ │ ├── 2026-01-22-document-review-system-design.md │ │ ├── 2026-02-19-visual-brainstorming-refactor-design.md │ │ └── 2026-03-11-zero-dep-brainstorm-server-design.md │ ├── testing.md │ └── windows/ │ └── polyglot-hooks.md ├── gemini-extension.json ├── hooks/ │ ├── hooks-cursor.json │ ├── hooks.json │ ├── run-hook.cmd │ └── session-start ├── package.json ├── skills/ │ ├── brainstorming/ │ │ ├── SKILL.md │ │ ├── scripts/ │ │ │ ├── frame-template.html │ │ │ ├── helper.js │ │ │ ├── server.cjs │ │ │ ├── start-server.sh │ │ │ └── stop-server.sh │ │ ├── spec-document-reviewer-prompt.md │ │ └── visual-companion.md │ ├── dispatching-parallel-agents/ │ │ └── SKILL.md │ ├── executing-plans/ │ │ └── SKILL.md │ ├── finishing-a-development-branch/ │ │ └── SKILL.md │ ├── receiving-code-review/ │ │ └── SKILL.md │ ├── requesting-code-review/ │ │ ├── SKILL.md │ │ └── code-reviewer.md │ ├── subagent-driven-development/ │ │ ├── SKILL.md │ │ ├── code-quality-reviewer-prompt.md │ │ ├── implementer-prompt.md │ │ └── spec-reviewer-prompt.md │ ├── systematic-debugging/ │ │ ├── CREATION-LOG.md │ │ ├── SKILL.md │ │ ├── condition-based-waiting-example.ts │ │ ├── condition-based-waiting.md │ │ ├── defense-in-depth.md │ │ ├── find-polluter.sh │ │ ├── root-cause-tracing.md │ │ ├── test-academic.md │ │ ├── test-pressure-1.md │ │ ├── test-pressure-2.md │ │ └── test-pressure-3.md │ ├── test-driven-development/ │ │ ├── SKILL.md │ │ └── testing-anti-patterns.md │ ├── using-git-worktrees/ │ │ └── SKILL.md │ ├── using-superpowers/ │ │ ├── SKILL.md │ │ └── references/ │ │ ├── codex-tools.md │ │ └── gemini-tools.md │ ├── verification-before-completion/ │ │ └── SKILL.md │ ├── writing-plans/ │ │ ├── SKILL.md │ │ └── plan-document-reviewer-prompt.md │ └── writing-skills/ │ ├── SKILL.md │ ├── anthropic-best-practices.md │ ├── examples/ │ │ └── CLAUDE_MD_TESTING.md │ ├── graphviz-conventions.dot │ ├── persuasion-principles.md │ ├── render-graphs.js │ └── testing-skills-with-subagents.md └── tests/ ├── brainstorm-server/ │ ├── package.json │ ├── server.test.js │ ├── windows-lifecycle.test.sh │ └── ws-protocol.test.js ├── claude-code/ │ ├── README.md │ ├── analyze-token-usage.py │ ├── run-skill-tests.sh │ ├── test-document-review-system.sh │ ├── test-helpers.sh │ ├── test-subagent-driven-development-integration.sh │ └── test-subagent-driven-development.sh ├── explicit-skill-requests/ │ ├── prompts/ │ │ ├── action-oriented.txt │ │ ├── after-planning-flow.txt │ │ ├── claude-suggested-it.txt │ │ ├── i-know-what-sdd-means.txt │ │ ├── mid-conversation-execute-plan.txt │ │ ├── please-use-brainstorming.txt │ │ ├── skip-formalities.txt │ │ ├── subagent-driven-development-please.txt │ │ └── use-systematic-debugging.txt │ ├── run-all.sh │ ├── run-claude-describes-sdd.sh │ ├── run-extended-multiturn-test.sh │ ├── run-haiku-test.sh │ ├── run-multiturn-test.sh │ └── run-test.sh ├── opencode/ │ ├── run-tests.sh │ ├── setup.sh │ ├── test-plugin-loading.sh │ ├── test-priority.sh │ └── test-tools.sh ├── skill-triggering/ │ ├── prompts/ │ │ ├── dispatching-parallel-agents.txt │ │ ├── executing-plans.txt │ │ ├── requesting-code-review.txt │ │ ├── systematic-debugging.txt │ │ ├── test-driven-development.txt │ │ └── writing-plans.txt │ ├── run-all.sh │ └── run-test.sh └── subagent-driven-dev/ ├── go-fractals/ │ ├── design.md │ ├── plan.md │ └── scaffold.sh ├── run-test.sh └── svelte-todo/ ├── design.md ├── plan.md └── scaffold.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .claude-plugin/marketplace.json ================================================ { "name": "superpowers-dev", "description": "Development marketplace for Superpowers core skills library", "owner": { "name": "Jesse Vincent", "email": "jesse@fsck.com" }, "plugins": [ { "name": "superpowers", "description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques", "version": "5.0.5", "source": "./", "author": { "name": "Jesse Vincent", "email": "jesse@fsck.com" } } ] } ================================================ FILE: .claude-plugin/plugin.json ================================================ { "name": "superpowers", "description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques", "version": "5.0.5", "author": { "name": "Jesse Vincent", "email": "jesse@fsck.com" }, "homepage": "https://github.com/obra/superpowers", "repository": "https://github.com/obra/superpowers", "license": "MIT", "keywords": ["skills", "tdd", "debugging", "collaboration", "best-practices", "workflows"] } ================================================ FILE: .codex/INSTALL.md ================================================ # Installing Superpowers for Codex Enable superpowers skills in Codex via native skill discovery. Just clone and symlink. ## Prerequisites - Git ## Installation 1. **Clone the superpowers repository:** ```bash git clone https://github.com/obra/superpowers.git ~/.codex/superpowers ``` 2. **Create the skills symlink:** ```bash mkdir -p ~/.agents/skills ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers ``` **Windows (PowerShell):** ```powershell New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills" cmd /c mklink /J "$env:USERPROFILE\.agents\skills\superpowers" "$env:USERPROFILE\.codex\superpowers\skills" ``` 3. **Restart Codex** (quit and relaunch the CLI) to discover the skills. ## Migrating from old bootstrap If you installed superpowers before native skill discovery, you need to: 1. **Update the repo:** ```bash cd ~/.codex/superpowers && git pull ``` 2. **Create the skills symlink** (step 2 above) — this is the new discovery mechanism. 3. **Remove the old bootstrap block** from `~/.codex/AGENTS.md` — any block referencing `superpowers-codex bootstrap` is no longer needed. 4. **Restart Codex.** ## Verify ```bash ls -la ~/.agents/skills/superpowers ``` You should see a symlink (or junction on Windows) pointing to your superpowers skills directory. ## Updating ```bash cd ~/.codex/superpowers && git pull ``` Skills update instantly through the symlink. ## Uninstalling ```bash rm ~/.agents/skills/superpowers ``` Optionally delete the clone: `rm -rf ~/.codex/superpowers`. ================================================ FILE: .cursor-plugin/plugin.json ================================================ { "name": "superpowers", "displayName": "Superpowers", "description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques", "version": "5.0.5", "author": { "name": "Jesse Vincent", "email": "jesse@fsck.com" }, "homepage": "https://github.com/obra/superpowers", "repository": "https://github.com/obra/superpowers", "license": "MIT", "keywords": ["skills", "tdd", "debugging", "collaboration", "best-practices", "workflows"], "skills": "./skills/", "agents": "./agents/", "commands": "./commands/", "hooks": "./hooks/hooks-cursor.json" } ================================================ FILE: .gitattributes ================================================ # Ensure shell scripts always have LF line endings *.sh text eol=lf hooks/session-start text eol=lf # Ensure the polyglot wrapper keeps LF (it's parsed by both cmd and bash) *.cmd text eol=lf # Common text files *.md text eol=lf *.json text eol=lf *.js text eol=lf *.mjs text eol=lf *.ts text eol=lf # Explicitly mark binary files *.png binary *.jpg binary *.gif binary ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [obra] ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug Report about: Something isn't working as expected labels: bug --- - [ ] I searched existing issues and this is not a duplicate ## Environment | Field | Value | |-------|-------| | Superpowers version | | | Harness (Claude Code, Cursor, etc.) | | | Harness version | | | Model | | | OS + shell | | ## Is this a Superpowers issue or a platform issue? - [ ] I confirmed this issue does not occur without Superpowers installed ## What happened? ## Steps to reproduce 1. 2. 3. ## Expected behavior ## Actual behavior ## Debug log or conversation transcript ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Questions & Help url: https://discord.gg/Jd8Vphy9jq about: For usage questions, troubleshooting help, and general discussion, please visit our Discord instead of opening an issue. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature Request about: Propose a change or addition to Superpowers labels: enhancement --- - [ ] I searched existing issues and this has not been proposed before ## What problem does this solve? ## Proposed solution ## What alternatives did you consider? ## Is this appropriate for core Superpowers? ## Context ================================================ FILE: .github/ISSUE_TEMPLATE/platform_support.md ================================================ --- name: IDE / Platform Support Request about: Request support for a new IDE, editor, or AI coding tool labels: platform-support --- - [ ] I searched existing issues for this IDE/platform ## Which IDE or platform? ## Does this tool have a plugin or extension system? ## Have you tried manual installation? ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## What problem are you trying to solve? ## What does this PR change? ## Is this change appropriate for the core library? ## What alternatives did you consider? ## Does this PR contain multiple unrelated changes? ## Existing PRs - [ ] I have reviewed all open AND closed PRs for duplicates or prior art - Related PRs: ## Environment tested | Harness (e.g. Claude Code, Cursor) | Harness version | Model | Model version/ID | |-------------------------------------|-----------------|-------|------------------| | | | | | ## Evaluation - What was the initial prompt you (or your human partner) used to start the session that led to this change? - How many eval sessions did you run AFTER making the change? - How did outcomes change compared to before the change? ## Rigor - [ ] If this is a skills change: I used `superpowers:writing-skills` and completed adversarial pressure testing (paste results below) - [ ] This change was tested adversarially, not just on the happy path - [ ] I did not modify carefully-tuned content (Red Flags table, rationalizations, "human partner" language) without extensive evals showing the change is an improvement ## Human review - [ ] A human has reviewed the COMPLETE proposed diff before submission ================================================ FILE: .gitignore ================================================ .worktrees/ .private-journal/ .claude/ .DS_Store node_modules/ inspo triage/ ================================================ FILE: .opencode/INSTALL.md ================================================ # Installing Superpowers for OpenCode ## Prerequisites - [OpenCode.ai](https://opencode.ai) installed ## Installation Add superpowers to the `plugin` array in your `opencode.json` (global or project-level): ```json { "plugin": ["superpowers@git+https://github.com/obra/superpowers.git"] } ``` Restart OpenCode. That's it — the plugin auto-installs and registers all skills. Verify by asking: "Tell me about your superpowers" ## Migrating from the old symlink-based install If you previously installed superpowers using `git clone` and symlinks, remove the old setup: ```bash # Remove old symlinks rm -f ~/.config/opencode/plugins/superpowers.js rm -rf ~/.config/opencode/skills/superpowers # Optionally remove the cloned repo rm -rf ~/.config/opencode/superpowers # Remove skills.paths from opencode.json if you added one for superpowers ``` Then follow the installation steps above. ## Usage Use OpenCode's native `skill` tool: ``` use skill tool to list skills use skill tool to load superpowers/brainstorming ``` ## Updating Superpowers updates automatically when you restart OpenCode. To pin a specific version: ```json { "plugin": ["superpowers@git+https://github.com/obra/superpowers.git#v5.0.3"] } ``` ## Troubleshooting ### Plugin not loading 1. Check logs: `opencode run --print-logs "hello" 2>&1 | grep -i superpowers` 2. Verify the plugin line in your `opencode.json` 3. Make sure you're running a recent version of OpenCode ### Skills not found 1. Use `skill` tool to list what's discovered 2. Check that the plugin is loading (see above) ### Tool mapping When skills reference Claude Code tools: - `TodoWrite` → `todowrite` - `Task` with subagents → `@mention` syntax - `Skill` tool → OpenCode's native `skill` tool - File operations → your native tools ## Getting Help - Report issues: https://github.com/obra/superpowers/issues - Full documentation: https://github.com/obra/superpowers/blob/main/docs/README.opencode.md ================================================ FILE: .opencode/plugins/superpowers.js ================================================ /** * Superpowers plugin for OpenCode.ai * * Injects superpowers bootstrap context via system prompt transform. * Auto-registers skills directory via config hook (no symlinks needed). */ import path from 'path'; import fs from 'fs'; import os from 'os'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Simple frontmatter extraction (avoid dependency on skills-core for bootstrap) const extractAndStripFrontmatter = (content) => { const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); if (!match) return { frontmatter: {}, content }; const frontmatterStr = match[1]; const body = match[2]; const frontmatter = {}; for (const line of frontmatterStr.split('\n')) { const colonIdx = line.indexOf(':'); if (colonIdx > 0) { const key = line.slice(0, colonIdx).trim(); const value = line.slice(colonIdx + 1).trim().replace(/^["']|["']$/g, ''); frontmatter[key] = value; } } return { frontmatter, content: body }; }; // Normalize a path: trim whitespace, expand ~, resolve to absolute const normalizePath = (p, homeDir) => { if (!p || typeof p !== 'string') return null; let normalized = p.trim(); if (!normalized) return null; if (normalized.startsWith('~/')) { normalized = path.join(homeDir, normalized.slice(2)); } else if (normalized === '~') { normalized = homeDir; } return path.resolve(normalized); }; export const SuperpowersPlugin = async ({ client, directory }) => { const homeDir = os.homedir(); const superpowersSkillsDir = path.resolve(__dirname, '../../skills'); const envConfigDir = normalizePath(process.env.OPENCODE_CONFIG_DIR, homeDir); const configDir = envConfigDir || path.join(homeDir, '.config/opencode'); // Helper to generate bootstrap content const getBootstrapContent = () => { // Try to load using-superpowers skill const skillPath = path.join(superpowersSkillsDir, 'using-superpowers', 'SKILL.md'); if (!fs.existsSync(skillPath)) return null; const fullContent = fs.readFileSync(skillPath, 'utf8'); const { content } = extractAndStripFrontmatter(fullContent); const toolMapping = `**Tool Mapping for OpenCode:** When skills reference tools you don't have, substitute OpenCode equivalents: - \`TodoWrite\` → \`todowrite\` - \`Task\` tool with subagents → Use OpenCode's subagent system (@mention) - \`Skill\` tool → OpenCode's native \`skill\` tool - \`Read\`, \`Write\`, \`Edit\`, \`Bash\` → Your native tools **Skills location:** Superpowers skills are in \`${configDir}/skills/superpowers/\` Use OpenCode's native \`skill\` tool to list and load skills.`; return ` You have superpowers. **IMPORTANT: The using-superpowers skill content is included below. It is ALREADY LOADED - you are currently following it. Do NOT use the skill tool to load "using-superpowers" again - that would be redundant.** ${content} ${toolMapping} `; }; return { // Inject skills path into live config so OpenCode discovers superpowers skills // without requiring manual symlinks or config file edits. // This works because Config.get() returns a cached singleton — modifications // here are visible when skills are lazily discovered later. config: async (config) => { config.skills = config.skills || {}; config.skills.paths = config.skills.paths || []; if (!config.skills.paths.includes(superpowersSkillsDir)) { config.skills.paths.push(superpowersSkillsDir); } }, // Use system prompt transform to inject bootstrap (fixes #226 agent reset bug) 'experimental.chat.system.transform': async (_input, output) => { const bootstrap = getBootstrapContent(); if (bootstrap) { (output.system ||= []).push(bootstrap); } } }; }; ================================================ FILE: CHANGELOG.md ================================================ # Changelog ## [5.0.5] - 2026-03-17 ### Fixed - **Brainstorm server ESM fix**: Renamed `server.js` → `server.cjs` so the brainstorming server starts correctly on Node.js 22+ where the root `package.json` `"type": "module"` caused `require()` to fail. ([PR #784](https://github.com/obra/superpowers/pull/784) by @sarbojitrana, fixes [#774](https://github.com/obra/superpowers/issues/774), [#780](https://github.com/obra/superpowers/issues/780), [#783](https://github.com/obra/superpowers/issues/783)) - **Brainstorm owner-PID on Windows**: Skip `BRAINSTORM_OWNER_PID` lifecycle monitoring on Windows/MSYS2 where the PID namespace is invisible to Node.js. Prevents the server from self-terminating after 60 seconds. The 30-minute idle timeout remains as the safety net. ([#770](https://github.com/obra/superpowers/issues/770), docs from [PR #768](https://github.com/obra/superpowers/pull/768) by @lucasyhzhu-debug) - **stop-server.sh reliability**: Verify the server process actually died before reporting success. Waits up to 2 seconds for graceful shutdown, escalates to `SIGKILL`, and reports failure if the process survives. ([#723](https://github.com/obra/superpowers/issues/723)) ### Changed - **Execution handoff**: Restore user choice between subagent-driven-development and executing-plans after plan writing. Subagent-driven is recommended but no longer mandatory. (Reverts `5e51c3e`) ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at jesse@primeradiant.com. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. ================================================ FILE: GEMINI.md ================================================ @./skills/using-superpowers/SKILL.md @./skills/using-superpowers/references/gemini-tools.md ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2025 Jesse Vincent Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Superpowers Superpowers is a complete software development workflow for your coding agents, built on top of a set of composable "skills" and some initial instructions that make sure your agent uses them. ## How it works It starts from the moment you fire up your coding agent. As soon as it sees that you're building something, it *doesn't* just jump into trying to write code. Instead, it steps back and asks you what you're really trying to do. Once it's teased a spec out of the conversation, it shows it to you in chunks short enough to actually read and digest. After you've signed off on the design, your agent puts together an implementation plan that's clear enough for an enthusiastic junior engineer with poor taste, no judgement, no project context, and an aversion to testing to follow. It emphasizes true red/green TDD, YAGNI (You Aren't Gonna Need It), and DRY. Next up, once you say "go", it launches a *subagent-driven-development* process, having agents work through each engineering task, inspecting and reviewing their work, and continuing forward. It's not uncommon for Claude to be able to work autonomously for a couple hours at a time without deviating from the plan you put together. There's a bunch more to it, but that's the core of the system. And because the skills trigger automatically, you don't need to do anything special. Your coding agent just has Superpowers. ## Sponsorship If Superpowers has helped you do stuff that makes money and you are so inclined, I'd greatly appreciate it if you'd consider [sponsoring my opensource work](https://github.com/sponsors/obra). Thanks! - Jesse ## Installation **Note:** Installation differs by platform. Claude Code or Cursor have built-in plugin marketplaces. Codex and OpenCode require manual setup. ### Claude Code Official Marketplace Superpowers is available via the [official Claude plugin marketplace](https://claude.com/plugins/superpowers) Install the plugin from Claude marketplace: ```bash /plugin install superpowers@claude-plugins-official ``` ### Claude Code (via Plugin Marketplace) In Claude Code, register the marketplace first: ```bash /plugin marketplace add obra/superpowers-marketplace ``` Then install the plugin from this marketplace: ```bash /plugin install superpowers@superpowers-marketplace ``` ### Cursor (via Plugin Marketplace) In Cursor Agent chat, install from marketplace: ```text /add-plugin superpowers ``` or search for "superpowers" in the plugin marketplace. ### Codex Tell Codex: ``` Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md ``` **Detailed docs:** [docs/README.codex.md](docs/README.codex.md) ### OpenCode Tell OpenCode: ``` Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.opencode/INSTALL.md ``` **Detailed docs:** [docs/README.opencode.md](docs/README.opencode.md) ### Gemini CLI ```bash gemini extensions install https://github.com/obra/superpowers ``` To update: ```bash gemini extensions update superpowers ``` ### Verify Installation Start a new session in your chosen platform and ask for something that should trigger a skill (for example, "help me plan this feature" or "let's debug this issue"). The agent should automatically invoke the relevant superpowers skill. ## The Basic Workflow 1. **brainstorming** - Activates before writing code. Refines rough ideas through questions, explores alternatives, presents design in sections for validation. Saves design document. 2. **using-git-worktrees** - Activates after design approval. Creates isolated workspace on new branch, runs project setup, verifies clean test baseline. 3. **writing-plans** - Activates with approved design. Breaks work into bite-sized tasks (2-5 minutes each). Every task has exact file paths, complete code, verification steps. 4. **subagent-driven-development** or **executing-plans** - Activates with plan. Dispatches fresh subagent per task with two-stage review (spec compliance, then code quality), or executes in batches with human checkpoints. 5. **test-driven-development** - Activates during implementation. Enforces RED-GREEN-REFACTOR: write failing test, watch it fail, write minimal code, watch it pass, commit. Deletes code written before tests. 6. **requesting-code-review** - Activates between tasks. Reviews against plan, reports issues by severity. Critical issues block progress. 7. **finishing-a-development-branch** - Activates when tasks complete. Verifies tests, presents options (merge/PR/keep/discard), cleans up worktree. **The agent checks for relevant skills before any task.** Mandatory workflows, not suggestions. ## What's Inside ### Skills Library **Testing** - **test-driven-development** - RED-GREEN-REFACTOR cycle (includes testing anti-patterns reference) **Debugging** - **systematic-debugging** - 4-phase root cause process (includes root-cause-tracing, defense-in-depth, condition-based-waiting techniques) - **verification-before-completion** - Ensure it's actually fixed **Collaboration** - **brainstorming** - Socratic design refinement - **writing-plans** - Detailed implementation plans - **executing-plans** - Batch execution with checkpoints - **dispatching-parallel-agents** - Concurrent subagent workflows - **requesting-code-review** - Pre-review checklist - **receiving-code-review** - Responding to feedback - **using-git-worktrees** - Parallel development branches - **finishing-a-development-branch** - Merge/PR decision workflow - **subagent-driven-development** - Fast iteration with two-stage review (spec compliance, then code quality) **Meta** - **writing-skills** - Create new skills following best practices (includes testing methodology) - **using-superpowers** - Introduction to the skills system ## Philosophy - **Test-Driven Development** - Write tests first, always - **Systematic over ad-hoc** - Process over guessing - **Complexity reduction** - Simplicity as primary goal - **Evidence over claims** - Verify before declaring success Read more: [Superpowers for Claude Code](https://blog.fsck.com/2025/10/09/superpowers/) ## Contributing Skills live directly in this repository. To contribute: 1. Fork the repository 2. Create a branch for your skill 3. Follow the `writing-skills` skill for creating and testing new skills 4. Submit a PR See `skills/writing-skills/SKILL.md` for the complete guide. ## Updating Skills update automatically when you update the plugin: ```bash /plugin update superpowers ``` ## License MIT License - see LICENSE file for details ## Community Superpowers is built by [Jesse Vincent](https://blog.fsck.com) and the rest of the folks at [Prime Radiant](https://primeradiant.com). For community support, questions, and sharing what you're building with Superpowers, join us on [Discord](https://discord.gg/Jd8Vphy9jq). ## Support - **Discord**: [Join us on Discord](https://discord.gg/Jd8Vphy9jq) - **Issues**: https://github.com/obra/superpowers/issues - **Marketplace**: https://github.com/obra/superpowers-marketplace ================================================ FILE: RELEASE-NOTES.md ================================================ # Superpowers Release Notes ## v5.0.5 (2026-03-17) ### Bug Fixes - **Brainstorm server ESM fix** — renamed `server.js` → `server.cjs` so the brainstorming server starts correctly on Node.js 22+ where the root `package.json` `"type": "module"` caused `require()` to fail. (PR #784 by @sarbojitrana, fixes #774, #780, #783) - **Brainstorm owner-PID on Windows** — skip PID lifecycle monitoring on Windows/MSYS2 where the PID namespace is invisible to Node.js, preventing the server from self-terminating after 60 seconds. (#770, docs from PR #768 by @lucasyhzlu-debug) - **stop-server.sh reliability** — verify the server process actually died before reporting success. SIGTERM + 2s wait + SIGKILL fallback. (#723) ### Changed - **Execution handoff** — restore user choice between subagent-driven and inline execution after plan writing. Subagent-driven is recommended but no longer mandatory. ## v5.0.4 (2026-03-16) ### Review Loop Refinements Dramatically reduces token usage and speeds up spec and plan reviews by eliminating unnecessary review passes and tightening reviewer focus. - **Single whole-plan review** — plan reviewer now reviews the complete plan in one pass instead of chunk-by-chunk. Removed all chunk-related concepts (`## Chunk N:` headings, 1000-line chunk limits, per-chunk dispatch). - **Raised the bar for blocking issues** — both spec and plan reviewer prompts now include a "Calibration" section: only flag issues that would cause real problems during implementation. Minor wording, stylistic preferences, and formatting quibbles should not block approval. - **Reduced max review iterations** — from 5 to 3 for both spec and plan review loops. If the reviewer is calibrated correctly, 3 rounds is plenty. - **Streamlined reviewer checklists** — spec reviewer trimmed from 7 categories to 5; plan reviewer from 7 to 4. Removed formatting-focused checks (task syntax, chunk size) in favor of substance (buildability, spec alignment). ### OpenCode - **One-line plugin install** — OpenCode plugin now auto-registers the skills directory via a `config` hook. No symlinks or `skills.paths` config needed. Install is just adding one line to `opencode.json`. (PR #753) - **Added `package.json`** so OpenCode can install superpowers as an npm package from git. ### Bug Fixes - **Verify server actually stopped** — `stop-server.sh` now confirms the process is dead before reporting success. SIGTERM + 2s wait + SIGKILL fallback. Reports failure if the process survives. (PR #751) - **Generic agent language** — brainstorm companion waiting page now says "the agent" instead of "Claude". ## v5.0.3 (2026-03-15) ### Cursor Support - **Cursor hooks** — added `hooks/hooks-cursor.json` with Cursor's camelCase format (`sessionStart`, `version: 1`) and updated `.cursor-plugin/plugin.json` to reference it. Fixed platform detection in `session-start` to check `CURSOR_PLUGIN_ROOT` first (Cursor may also set `CLAUDE_PLUGIN_ROOT`). (Based on PR #709) ### Bug Fixes - **Stop firing SessionStart hook on `--resume`** — the startup hook was re-injecting context on resumed sessions, which already have the context in their conversation history. The hook now fires only on `startup`, `clear`, and `compact`. - **Bash 5.3+ hook hang** — replaced heredoc (`cat <` on served HTML pages ### Subagent Context Isolation - All delegation skills (brainstorming, dispatching-parallel-agents, requesting-code-review, subagent-driven-development, writing-plans) now include context isolation principle - Subagents receive only the context they need, preventing context window pollution ## v5.0.1 (2026-03-10) ### Agentskills Compliance **Brainstorm-server moved into skill directory** - Moved `lib/brainstorm-server/` → `skills/brainstorming/scripts/` per the [agentskills.io](https://agentskills.io) specification - All `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/` references replaced with relative `scripts/` paths - Skills are now fully portable across platforms — no platform-specific env vars needed to locate scripts - `lib/` directory removed (was the last remaining content) ### New Features **Gemini CLI extension** - Native Gemini CLI extension support via `gemini-extension.json` and `GEMINI.md` at repo root - `GEMINI.md` @imports `using-superpowers` skill and tool mapping table at session start - Gemini CLI tool mapping reference (`skills/using-superpowers/references/gemini-tools.md`) — translates Claude Code tool names (Read, Write, Edit, Bash, etc.) to Gemini CLI equivalents (read_file, write_file, replace, etc.) - Documents Gemini CLI limitations: no subagent support, skills fall back to `executing-plans` - Extension root at repo root for cross-platform compatibility (avoids Windows symlink issues) - Install instructions added to README ### Improvements **Multi-platform brainstorm server launch** - Per-platform launch instructions in visual-companion.md: Claude Code (default mode), Codex (auto-foreground via `CODEX_CI`), Gemini CLI (`--foreground` with `is_background`), and fallback for other environments - Server now writes startup JSON to `$SCREEN_DIR/.server-info` so agents can find the URL and port even when stdout is hidden by background execution **Brainstorm server dependencies bundled** - `node_modules` vendored into the repo so the brainstorm server works immediately on fresh plugin installs without requiring `npm` at runtime - Removed `fsevents` from bundled deps (macOS-only native binary; chokidar falls back gracefully without it) - Fallback auto-install via `npm install` if `node_modules` is missing **OpenCode tool mapping fix** - `TodoWrite` → `todowrite` (was incorrectly mapped to `update_plan`); verified against OpenCode source ### Bug Fixes **Windows/Linux: single quotes break SessionStart hook** (#577, #529, #644, PR #585) - Single quotes around `${CLAUDE_PLUGIN_ROOT}` in hooks.json fail on Windows (cmd.exe doesn't recognize single quotes as path delimiters) and on Linux (single quotes prevent variable expansion) - Fix: replaced single quotes with escaped double quotes — works across macOS bash, Windows cmd.exe, Windows Git Bash, and Linux, with and without spaces in paths - Verified on Windows 11 (NT 10.0.26200.0) with Claude Code 2.1.72 and Git for Windows **Brainstorming spec review loop skipped** (#677) - The spec review loop (dispatch spec-document-reviewer subagent, iterate until approved) existed in the prose "After the Design" section but was missing from the checklist and process flow diagram - Since agents follow the diagram and checklist more reliably than prose, the spec review step was being skipped entirely - Added step 7 (spec review loop) to the checklist and corresponding nodes to the dot graph - Tested with `claude --plugin-dir` and `claude-session-driver`: worker now correctly dispatches the reviewer **Cursor install command** (PR #676) - Fixed Cursor install command in README: `/plugin-add` → `/add-plugin` (confirmed via Cursor 2.5 release announcement) **User review gate in brainstorming** (#565) - Added explicit user review step between spec completion and writing-plans handoff - User must approve the spec before implementation planning begins - Checklist, process flow, and prose updated with the new gate **Session-start hook emits context only once per platform** - Hook now detects whether it's running in Claude Code or another platform - Emits `hookSpecificOutput` for Claude Code, `additional_context` for others — prevents double context injection **Linting fix in token analysis script** - `except:` → `except Exception:` in `tests/claude-code/analyze-token-usage.py` ### Maintenance **Removed dead code** - Deleted `lib/skills-core.js` and its test (`tests/opencode/test-skills-core.js`) — unused since February 2026 - Removed skills-core existence check from `tests/opencode/test-plugin-loading.sh` ### Community - @karuturi — Claude Code official marketplace install instructions (PR #610) - @mvanhorn — session-start hook dual-emit fix, OpenCode tool mapping fix - @daniel-graham — linting fix for bare except - PR #585 author — Windows/Linux hooks quoting fix --- ## v5.0.0 (2026-03-09) ### Breaking Changes **Specs and plans directory restructured** - Specs (brainstorming output) now save to `docs/superpowers/specs/YYYY-MM-DD--design.md` - Plans (writing-plans output) now save to `docs/superpowers/plans/YYYY-MM-DD-.md` - User preferences for spec/plan locations override these defaults - All internal skill references, test files, and example paths updated to match - Migration: move existing files from `docs/plans/` to new locations if desired **Subagent-driven development mandatory on capable harnesses** Writing-plans no longer offers a choice between subagent-driven and executing-plans. On harnesses with subagent support (Claude Code, Codex), subagent-driven-development is required. Executing-plans is reserved for harnesses without subagent capability, and now tells the user that Superpowers works better on a subagent-capable platform. **Executing-plans no longer batches** Removed the "execute 3 tasks then stop for review" pattern. Plans now execute continuously, stopping only for blockers. **Slash commands deprecated** `/brainstorm`, `/write-plan`, and `/execute-plan` now show deprecation notices pointing users to the corresponding skills. Commands will be removed in the next major release. ### New Features **Visual brainstorming companion** Optional browser-based companion for brainstorming sessions. When a topic would benefit from visuals, the brainstorming skill offers to show mockups, diagrams, comparisons, and other content in a browser window alongside terminal conversation. - `lib/brainstorm-server/` — WebSocket server with browser helper library, session management scripts, and dark/light themed frame template ("Superpowers Brainstorming" with GitHub link) - `skills/brainstorming/visual-companion.md` — Progressive disclosure guide for server workflow, screen authoring, and feedback collection - Brainstorming skill adds a visual companion decision point to its process flow: after exploring project context, the skill evaluates whether upcoming questions involve visual content and offers the companion in its own message - Per-question decision: even after accepting, each question is evaluated for whether browser or terminal is more appropriate - Integration tests in `tests/brainstorm-server/` **Document review system** Automated review loops for spec and plan documents using subagent dispatch: - `skills/brainstorming/spec-document-reviewer-prompt.md` — Reviewer checks completeness, consistency, architecture, and YAGNI - `skills/writing-plans/plan-document-reviewer-prompt.md` — Reviewer checks spec alignment, task decomposition, file structure, and file size - Brainstorming dispatches spec reviewer after writing the design doc - Writing-plans includes chunk-based plan review loop after each section - Review loops repeat until approved or escalate after 5 iterations - End-to-end tests in `tests/claude-code/test-document-review-system.sh` - Design spec and implementation plan in `docs/superpowers/` **Architecture guidance across the skill pipeline** Design-for-isolation and file-size-awareness guidance added to brainstorming, writing-plans, and subagent-driven-development: - **Brainstorming** — New sections: "Design for isolation and clarity" (clear boundaries, well-defined interfaces, independently testable units) and "Working in existing codebases" (follow existing patterns, targeted improvements only) - **Writing-plans** — New "File Structure" section: map out files and responsibilities before defining tasks. New "Scope Check" backstop: catch multi-subsystem specs that should have been decomposed during brainstorming - **SDD implementer** — New "Code Organization" section (follow plan's file structure, report concerns about growing files) and "When You're in Over Your Head" escalation guidance - **SDD code quality reviewer** — Now checks architecture, unit decomposition, plan conformance, and file growth - **Spec/plan reviewers** — Architecture and file size added to review criteria - **Scope assessment** — Brainstorming now assesses whether a project is too large for a single spec. Multi-subsystem requests are flagged early and decomposed into sub-projects, each with its own spec → plan → implementation cycle **Subagent-driven development improvements** - **Model selection** — Guidance for choosing model capability by task type: cheap models for mechanical implementation, standard for integration, capable for architecture and review - **Implementer status protocol** — Subagents now report DONE, DONE_WITH_CONCERNS, BLOCKED, or NEEDS_CONTEXT. Controller handles each status appropriately: re-dispatching with more context, upgrading model capability, breaking tasks apart, or escalating to human ### Improvements **Instruction priority hierarchy** Added explicit priority ordering to using-superpowers: 1. User's explicit instructions (CLAUDE.md, AGENTS.md, direct requests) — highest priority 2. Superpowers skills — override default system behavior 3. Default system prompt — lowest priority If CLAUDE.md or AGENTS.md says "don't use TDD" and a skill says "always use TDD," the user's instructions win. **SUBAGENT-STOP gate** Added `` block to using-superpowers. Subagents dispatched for specific tasks now skip the skill instead of activating the 1% rule and invoking full skill workflows. **Multi-platform improvements** - Codex tool mapping moved to progressive disclosure reference file (`references/codex-tools.md`) - Platform Adaptation pointer added so non-Claude-Code platforms can find tool equivalents - Plan headers now address "agentic workers" instead of "Claude" specifically - Collab feature requirement documented in `docs/README.codex.md` **Writing-plans template updates** - Plan steps now use checkbox syntax (`- [ ] **Step N:**`) for progress tracking - Plan header references both subagent-driven-development and executing-plans with platform-aware routing --- ## v4.3.1 (2026-02-21) ### Added **Cursor support** Superpowers now works with Cursor's plugin system. Includes a `.cursor-plugin/plugin.json` manifest and Cursor-specific installation instructions in the README. The SessionStart hook output now includes an `additional_context` field alongside the existing `hookSpecificOutput.additionalContext` for Cursor hook compatibility. ### Fixed **Windows: Restored polyglot wrapper for reliable hook execution (#518, #504, #491, #487, #466, #440)** Claude Code's `.sh` auto-detection on Windows was prepending `bash` to the hook command, breaking execution. The fix: - Renamed `session-start.sh` to `session-start` (extensionless) so auto-detection doesn't interfere - Restored `run-hook.cmd` polyglot wrapper with multi-location bash discovery (standard Git for Windows paths, then PATH fallback) - Exits silently if no bash is found rather than erroring - On Unix, the wrapper runs the script directly via `exec bash` - Uses POSIX-safe `dirname "$0"` path resolution (works on dash/sh, not just bash) This fixes SessionStart failures on Windows with spaces in paths, missing WSL, `set -euo pipefail` fragility on MSYS, and backslash mangling. ## v4.3.0 (2026-02-12) This fix should dramatically improve superpowers skills compliance and should reduce the chances of Claude entering its native plan mode unintentionally. ### Changed **Brainstorming skill now enforces its workflow instead of describing it** Models were skipping the design phase and jumping straight to implementation skills like frontend-design, or collapsing the entire brainstorming process into a single text block. The skill now uses hard gates, a mandatory checklist, and a graphviz process flow to enforce compliance: - ``: no implementation skills, code, or scaffolding until design is presented and user approves - Explicit checklist (6 items) that must be created as tasks and completed in order - Graphviz process flow with `writing-plans` as the only valid terminal state - Anti-pattern callout for "this is too simple to need a design" — the exact rationalization models use to skip the process - Design section sizing based on section complexity, not project complexity **Using-superpowers workflow graph intercepts EnterPlanMode** Added an `EnterPlanMode` intercept to the skill flow graph. When the model is about to enter Claude's native plan mode, it checks whether brainstorming has happened and routes through the brainstorming skill instead. Plan mode is never entered. ### Fixed **SessionStart hook now runs synchronously** Changed `async: true` to `async: false` in hooks.json. When async, the hook could fail to complete before the model's first turn, meaning using-superpowers instructions weren't in context for the first message. ## v4.2.0 (2026-02-05) ### Breaking Changes **Codex: Replaced bootstrap CLI with native skill discovery** The `superpowers-codex` bootstrap CLI, Windows `.cmd` wrapper, and related bootstrap content file have been removed. Codex now uses native skill discovery via `~/.agents/skills/superpowers/` symlink, so the old `use_skill`/`find_skills` CLI tools are no longer needed. Installation is now just clone + symlink (documented in INSTALL.md). No Node.js dependency required. The old `~/.codex/skills/` path is deprecated. ### Fixes **Windows: Fixed Claude Code 2.1.x hook execution (#331)** Claude Code 2.1.x changed how hooks execute on Windows: it now auto-detects `.sh` files in commands and prepends `bash`. This broke the polyglot wrapper pattern because `bash "run-hook.cmd" session-start.sh` tries to execute the `.cmd` file as a bash script. Fix: hooks.json now calls session-start.sh directly. Claude Code 2.1.x handles the bash invocation automatically. Also added .gitattributes to enforce LF line endings for shell scripts (fixes CRLF issues on Windows checkout). **Windows: SessionStart hook runs async to prevent terminal freeze (#404, #413, #414, #419)** The synchronous SessionStart hook blocked the TUI from entering raw mode on Windows, freezing all keyboard input. Running the hook async prevents the freeze while still injecting superpowers context. **Windows: Fixed O(n^2) `escape_for_json` performance** The character-by-character loop using `${input:$i:1}` was O(n^2) in bash due to substring copy overhead. On Windows Git Bash this took 60+ seconds. Replaced with bash parameter substitution (`${s//old/new}`) which runs each pattern as a single C-level pass — 7x faster on macOS, dramatically faster on Windows. **Codex: Fixed Windows/PowerShell invocation (#285, #243)** - Windows doesn't respect shebangs, so directly invoking the extensionless `superpowers-codex` script triggered an "Open with" dialog. All invocations now prefixed with `node`. - Fixed `~/` path expansion on Windows — PowerShell doesn't expand `~` when passed as an argument to `node`. Changed to `$HOME` which expands correctly in both bash and PowerShell. **Codex: Fixed path resolution in installer** Used `fileURLToPath()` instead of manual URL pathname parsing to correctly handle paths with spaces and special characters on all platforms. **Codex: Fixed stale skills path in writing-skills** Updated `~/.codex/skills/` reference (deprecated) to `~/.agents/skills/` for native discovery. ### Improvements **Worktree isolation now required before implementation** Added `using-git-worktrees` as a required skill for both `subagent-driven-development` and `executing-plans`. Implementation workflows now explicitly require setting up an isolated worktree before starting work, preventing accidental work directly on main. **Main branch protection softened to require explicit consent** Instead of prohibiting main branch work entirely, the skills now allow it with explicit user consent. More flexible while still ensuring users are aware of the implications. **Simplified installation verification** Removed `/help` command check and specific slash command list from verification steps. Skills are primarily invoked by describing what you want to do, not by running specific commands. **Codex: Clarified subagent tool mapping in bootstrap** Improved documentation of how Codex tools map to Claude Code equivalents for subagent workflows. ### Tests - Added worktree requirement test for subagent-driven-development - Added main branch red flag warning test - Fixed case sensitivity in skill recognition test assertions --- ## v4.1.1 (2026-01-23) ### Fixes **OpenCode: Standardized on `plugins/` directory per official docs (#343)** OpenCode's official documentation uses `~/.config/opencode/plugins/` (plural). Our docs previously used `plugin/` (singular). While OpenCode accepts both forms, we've standardized on the official convention to avoid confusion. Changes: - Renamed `.opencode/plugin/` to `.opencode/plugins/` in repo structure - Updated all installation docs (INSTALL.md, README.opencode.md) across all platforms - Updated test scripts to match **OpenCode: Fixed symlink instructions (#339, #342)** - Added explicit `rm` before `ln -s` (fixes "file already exists" errors on reinstall) - Added missing skills symlink step that was absent from INSTALL.md - Updated from deprecated `use_skill`/`find_skills` to native `skill` tool references --- ## v4.1.0 (2026-01-23) ### Breaking Changes **OpenCode: Switched to native skills system** Superpowers for OpenCode now uses OpenCode's native `skill` tool instead of custom `use_skill`/`find_skills` tools. This is a cleaner integration that works with OpenCode's built-in skill discovery. **Migration required:** Skills must be symlinked to `~/.config/opencode/skills/superpowers/` (see updated installation docs). ### Fixes **OpenCode: Fixed agent reset on session start (#226)** The previous bootstrap injection method using `session.prompt({ noReply: true })` caused OpenCode to reset the selected agent to "build" on first message. Now uses `experimental.chat.system.transform` hook which modifies the system prompt directly without side effects. **OpenCode: Fixed Windows installation (#232)** - Removed dependency on `skills-core.js` (eliminates broken relative imports when file is copied instead of symlinked) - Added comprehensive Windows installation docs for cmd.exe, PowerShell, and Git Bash - Documented proper symlink vs junction usage for each platform **Claude Code: Fixed Windows hook execution for Claude Code 2.1.x** Claude Code 2.1.x changed how hooks execute on Windows: it now auto-detects `.sh` files in commands and prepends `bash `. This broke the polyglot wrapper pattern because `bash "run-hook.cmd" session-start.sh` tries to execute the .cmd file as a bash script. Fix: hooks.json now calls session-start.sh directly. Claude Code 2.1.x handles the bash invocation automatically. Also added .gitattributes to enforce LF line endings for shell scripts (fixes CRLF issues on Windows checkout). --- ## v4.0.3 (2025-12-26) ### Improvements **Strengthened using-superpowers skill for explicit skill requests** Addressed a failure mode where Claude would skip invoking a skill even when the user explicitly requested it by name (e.g., "subagent-driven-development, please"). Claude would think "I know what that means" and start working directly instead of loading the skill. Changes: - Updated "The Rule" to say "Invoke relevant or requested skills" instead of "Check for skills" - emphasizing active invocation over passive checking - Added "BEFORE any response or action" - the original wording only mentioned "response" but Claude would sometimes take action without responding first - Added reassurance that invoking a wrong skill is okay - reduces hesitation - Added new red flag: "I know what that means" → Knowing the concept ≠ using the skill **Added explicit skill request tests** New test suite in `tests/explicit-skill-requests/` that verifies Claude correctly invokes skills when users request them by name. Includes single-turn and multi-turn test scenarios. ## v4.0.2 (2025-12-23) ### Fixes **Slash commands now user-only** Added `disable-model-invocation: true` to all three slash commands (`/brainstorm`, `/execute-plan`, `/write-plan`). Claude can no longer invoke these commands via the Skill tool—they're restricted to manual user invocation only. The underlying skills (`superpowers:brainstorming`, `superpowers:executing-plans`, `superpowers:writing-plans`) remain available for Claude to invoke autonomously. This change prevents confusion when Claude would invoke a command that just redirects to a skill anyway. ## v4.0.1 (2025-12-23) ### Fixes **Clarified how to access skills in Claude Code** Fixed a confusing pattern where Claude would invoke a skill via the Skill tool, then try to Read the skill file separately. The `using-superpowers` skill now explicitly states that the Skill tool loads skill content directly—no need to read files. - Added "How to Access Skills" section to `using-superpowers` - Changed "read the skill" → "invoke the skill" in instructions - Updated slash commands to use fully qualified skill names (e.g., `superpowers:brainstorming`) **Added GitHub thread reply guidance to receiving-code-review** (h/t @ralphbean) Added a note about replying to inline review comments in the original thread rather than as top-level PR comments. **Added automation-over-documentation guidance to writing-skills** (h/t @EthanJStark) Added guidance that mechanical constraints should be automated, not documented—save skills for judgment calls. ## v4.0.0 (2025-12-17) ### New Features **Two-stage code review in subagent-driven-development** Subagent workflows now use two separate review stages after each task: 1. **Spec compliance review** - Skeptical reviewer verifies implementation matches spec exactly. Catches missing requirements AND over-building. Won't trust implementer's report—reads actual code. 2. **Code quality review** - Only runs after spec compliance passes. Reviews for clean code, test coverage, maintainability. This catches the common failure mode where code is well-written but doesn't match what was requested. Reviews are loops, not one-shot: if reviewer finds issues, implementer fixes them, then reviewer checks again. Other subagent workflow improvements: - Controller provides full task text to workers (not file references) - Workers can ask clarifying questions before AND during work - Self-review checklist before reporting completion - Plan read once at start, extracted to TodoWrite New prompt templates in `skills/subagent-driven-development/`: - `implementer-prompt.md` - Includes self-review checklist, encourages questions - `spec-reviewer-prompt.md` - Skeptical verification against requirements - `code-quality-reviewer-prompt.md` - Standard code review **Debugging techniques consolidated with tools** `systematic-debugging` now bundles supporting techniques and tools: - `root-cause-tracing.md` - Trace bugs backward through call stack - `defense-in-depth.md` - Add validation at multiple layers - `condition-based-waiting.md` - Replace arbitrary timeouts with condition polling - `find-polluter.sh` - Bisection script to find which test creates pollution - `condition-based-waiting-example.ts` - Complete implementation from real debugging session **Testing anti-patterns reference** `test-driven-development` now includes `testing-anti-patterns.md` covering: - Testing mock behavior instead of real behavior - Adding test-only methods to production classes - Mocking without understanding dependencies - Incomplete mocks that hide structural assumptions **Skill test infrastructure** Three new test frameworks for validating skill behavior: `tests/skill-triggering/` - Validates skills trigger from naive prompts without explicit naming. Tests 6 skills to ensure descriptions alone are sufficient. `tests/claude-code/` - Integration tests using `claude -p` for headless testing. Verifies skill usage via session transcript (JSONL) analysis. Includes `analyze-token-usage.py` for cost tracking. `tests/subagent-driven-dev/` - End-to-end workflow validation with two complete test projects: - `go-fractals/` - CLI tool with Sierpinski/Mandelbrot (10 tasks) - `svelte-todo/` - CRUD app with localStorage and Playwright (12 tasks) ### Major Changes **DOT flowcharts as executable specifications** Rewrote key skills using DOT/GraphViz flowcharts as the authoritative process definition. Prose becomes supporting content. **The Description Trap** (documented in `writing-skills`): Discovered that skill descriptions override flowchart content when descriptions contain workflow summaries. Claude follows the short description instead of reading the detailed flowchart. Fix: descriptions must be trigger-only ("Use when X") with no process details. **Skill priority in using-superpowers** When multiple skills apply, process skills (brainstorming, debugging) now explicitly come before implementation skills. "Build X" triggers brainstorming first, then domain skills. **brainstorming trigger strengthened** Description changed to imperative: "You MUST use this before any creative work—creating features, building components, adding functionality, or modifying behavior." ### Breaking Changes **Skill consolidation** - Six standalone skills merged: - `root-cause-tracing`, `defense-in-depth`, `condition-based-waiting` → bundled in `systematic-debugging/` - `testing-skills-with-subagents` → bundled in `writing-skills/` - `testing-anti-patterns` → bundled in `test-driven-development/` - `sharing-skills` removed (obsolete) ### Other Improvements - **render-graphs.js** - Tool to extract DOT diagrams from skills and render to SVG - **Rationalizations table** in using-superpowers - Scannable format including new entries: "I need more context first", "Let me explore first", "This feels productive" - **docs/testing.md** - Guide to testing skills with Claude Code integration tests --- ## v3.6.2 (2025-12-03) ### Fixed - **Linux Compatibility**: Fixed polyglot hook wrapper (`run-hook.cmd`) to use POSIX-compliant syntax - Replaced bash-specific `${BASH_SOURCE[0]:-$0}` with standard `$0` on line 16 - Resolves "Bad substitution" error on Ubuntu/Debian systems where `/bin/sh` is dash - Fixes #141 --- ## v3.5.1 (2025-11-24) ### Changed - **OpenCode Bootstrap Refactor**: Switched from `chat.message` hook to `session.created` event for bootstrap injection - Bootstrap now injects at session creation via `session.prompt()` with `noReply: true` - Explicitly tells the model that using-superpowers is already loaded to prevent redundant skill loading - Consolidated bootstrap content generation into shared `getBootstrapContent()` helper - Cleaner single-implementation approach (removed fallback pattern) --- ## v3.5.0 (2025-11-23) ### Added - **OpenCode Support**: Native JavaScript plugin for OpenCode.ai - Custom tools: `use_skill` and `find_skills` - Message insertion pattern for skill persistence across context compaction - Automatic context injection via chat.message hook - Auto re-injection on session.compacted events - Three-tier skill priority: project > personal > superpowers - Project-local skills support (`.opencode/skills/`) - Shared core module (`lib/skills-core.js`) for code reuse with Codex - Automated test suite with proper isolation (`tests/opencode/`) - Platform-specific documentation (`docs/README.opencode.md`, `docs/README.codex.md`) ### Changed - **Refactored Codex Implementation**: Now uses shared `lib/skills-core.js` ES module - Eliminates code duplication between Codex and OpenCode - Single source of truth for skill discovery and parsing - Codex successfully loads ES modules via Node.js interop - **Improved Documentation**: Rewrote README to explain problem/solution clearly - Removed duplicate sections and conflicting information - Added complete workflow description (brainstorm → plan → execute → finish) - Simplified platform installation instructions - Emphasized skill-checking protocol over automatic activation claims --- ## v3.4.1 (2025-10-31) ### Improvements - Optimized superpowers bootstrap to eliminate redundant skill execution. The `using-superpowers` skill content is now provided directly in session context, with clear guidance to use the Skill tool only for other skills. This reduces overhead and prevents the confusing loop where agents would execute `using-superpowers` manually despite already having the content from session start. ## v3.4.0 (2025-10-30) ### Improvements - Simplified `brainstorming` skill to return to original conversational vision. Removed heavyweight 6-phase process with formal checklists in favor of natural dialogue: ask questions one at a time, then present design in 200-300 word sections with validation. Keeps documentation and implementation handoff features. ## v3.3.1 (2025-10-28) ### Improvements - Updated `brainstorming` skill to require autonomous recon before questioning, encourage recommendation-driven decisions, and prevent agents from delegating prioritization back to humans. - Applied writing clarity improvements to `brainstorming` skill following Strunk's "Elements of Style" principles (omitted needless words, converted negative to positive form, improved parallel construction). ### Bug Fixes - Clarified `writing-skills` guidance so it points to the correct agent-specific personal skill directories (`~/.claude/skills` for Claude Code, `~/.codex/skills` for Codex). ## v3.3.0 (2025-10-28) ### New Features **Experimental Codex Support** - Added unified `superpowers-codex` script with bootstrap/use-skill/find-skills commands - Cross-platform Node.js implementation (works on Windows, macOS, Linux) - Namespaced skills: `superpowers:skill-name` for superpowers skills, `skill-name` for personal - Personal skills override superpowers skills when names match - Clean skill display: shows name/description without raw frontmatter - Helpful context: shows supporting files directory for each skill - Tool mapping for Codex: TodoWrite→update_plan, subagents→manual fallback, etc. - Bootstrap integration with minimal AGENTS.md for automatic startup - Complete installation guide and bootstrap instructions specific to Codex **Key differences from Claude Code integration:** - Single unified script instead of separate tools - Tool substitution system for Codex-specific equivalents - Simplified subagent handling (manual work instead of delegation) - Updated terminology: "Superpowers skills" instead of "Core skills" ### Files Added - `.codex/INSTALL.md` - Installation guide for Codex users - `.codex/superpowers-bootstrap.md` - Bootstrap instructions with Codex adaptations - `.codex/superpowers-codex` - Unified Node.js executable with all functionality **Note:** Codex support is experimental. The integration provides core superpowers functionality but may require refinement based on user feedback. ## v3.2.3 (2025-10-23) ### Improvements **Updated using-superpowers skill to use Skill tool instead of Read tool** - Changed skill invocation instructions from Read tool to Skill tool - Updated description: "using Read tool" → "using Skill tool" - Updated step 3: "Use the Read tool" → "Use the Skill tool to read and run" - Updated rationalization list: "Read the current version" → "Run the current version" The Skill tool is the proper mechanism for invoking skills in Claude Code. This update corrects the bootstrap instructions to guide agents toward the correct tool. ### Files Changed - Updated: `skills/using-superpowers/SKILL.md` - Changed tool references from Read to Skill ## v3.2.2 (2025-10-21) ### Improvements **Strengthened using-superpowers skill against agent rationalization** - Added EXTREMELY-IMPORTANT block with absolute language about mandatory skill checking - "If even 1% chance a skill applies, you MUST read it" - "You do not have a choice. You cannot rationalize your way out." - Added MANDATORY FIRST RESPONSE PROTOCOL checklist - 5-step process agents must complete before any response - Explicit "responding without this = failure" consequence - Added Common Rationalizations section with 8 specific evasion patterns - "This is just a simple question" → WRONG - "I can check files quickly" → WRONG - "Let me gather information first" → WRONG - Plus 5 more common patterns observed in agent behavior These changes address observed agent behavior where they rationalize around skill usage despite clear instructions. The forceful language and pre-emptive counter-arguments aim to make non-compliance harder. ### Files Changed - Updated: `skills/using-superpowers/SKILL.md` - Added three layers of enforcement to prevent skill-skipping rationalization ## v3.2.1 (2025-10-20) ### New Features **Code reviewer agent now included in plugin** - Added `superpowers:code-reviewer` agent to plugin's `agents/` directory - Agent provides systematic code review against plans and coding standards - Previously required users to have personal agent configuration - All skill references updated to use namespaced `superpowers:code-reviewer` - Fixes #55 ### Files Changed - New: `agents/code-reviewer.md` - Agent definition with review checklist and output format - Updated: `skills/requesting-code-review/SKILL.md` - References to `superpowers:code-reviewer` - Updated: `skills/subagent-driven-development/SKILL.md` - References to `superpowers:code-reviewer` ## v3.2.0 (2025-10-18) ### New Features **Design documentation in brainstorming workflow** - Added Phase 4: Design Documentation to brainstorming skill - Design documents now written to `docs/plans/YYYY-MM-DD--design.md` before implementation - Restores functionality from original brainstorming command that was lost during skill conversion - Documents written before worktree setup and implementation planning - Tested with subagent to verify compliance under time pressure ### Breaking Changes **Skill reference namespace standardization** - All internal skill references now use `superpowers:` namespace prefix - Updated format: `superpowers:test-driven-development` (previously just `test-driven-development`) - Affects all REQUIRED SUB-SKILL, RECOMMENDED SUB-SKILL, and REQUIRED BACKGROUND references - Aligns with how skills are invoked using the Skill tool - Files updated: brainstorming, executing-plans, subagent-driven-development, systematic-debugging, testing-skills-with-subagents, writing-plans, writing-skills ### Improvements **Design vs implementation plan naming** - Design documents use `-design.md` suffix to prevent filename collisions - Implementation plans continue using existing `YYYY-MM-DD-.md` format - Both stored in `docs/plans/` directory with clear naming distinction ## v3.1.1 (2025-10-17) ### Bug Fixes - **Fixed command syntax in README** (#44) - Updated all command references to use correct namespaced syntax (`/superpowers:brainstorm` instead of `/brainstorm`). Plugin-provided commands are automatically namespaced by Claude Code to avoid conflicts between plugins. ## v3.1.0 (2025-10-17) ### Breaking Changes **Skill names standardized to lowercase** - All skill frontmatter `name:` fields now use lowercase kebab-case matching directory names - Examples: `brainstorming`, `test-driven-development`, `using-git-worktrees` - All skill announcements and cross-references updated to lowercase format - This ensures consistent naming across directory names, frontmatter, and documentation ### New Features **Enhanced brainstorming skill** - Added Quick Reference table showing phases, activities, and tool usage - Added copyable workflow checklist for tracking progress - Added decision flowchart for when to revisit earlier phases - Added comprehensive AskUserQuestion tool guidance with concrete examples - Added "Question Patterns" section explaining when to use structured vs open-ended questions - Restructured Key Principles as scannable table **Anthropic best practices integration** - Added `skills/writing-skills/anthropic-best-practices.md` - Official Anthropic skill authoring guide - Referenced in writing-skills SKILL.md for comprehensive guidance - Provides patterns for progressive disclosure, workflows, and evaluation ### Improvements **Skill cross-reference clarity** - All skill references now use explicit requirement markers: - `**REQUIRED BACKGROUND:**` - Prerequisites you must understand - `**REQUIRED SUB-SKILL:**` - Skills that must be used in workflow - `**Complementary skills:**` - Optional but helpful related skills - Removed old path format (`skills/collaboration/X` → just `X`) - Updated Integration sections with categorized relationships (Required vs Complementary) - Updated cross-reference documentation with best practices **Alignment with Anthropic best practices** - Fixed description grammar and voice (fully third-person) - Added Quick Reference tables for scanning - Added workflow checklists Claude can copy and track - Appropriate use of flowcharts for non-obvious decision points - Improved scannable table formats - All skills well under 500-line recommendation ### Bug Fixes - **Re-added missing command redirects** - Restored `commands/brainstorm.md` and `commands/write-plan.md` that were accidentally removed in v3.0 migration - Fixed `defense-in-depth` name mismatch (was `Defense-in-Depth-Validation`) - Fixed `receiving-code-review` name mismatch (was `Code-Review-Reception`) - Fixed `commands/brainstorm.md` reference to correct skill name - Removed references to non-existent related skills ### Documentation **writing-skills improvements** - Updated cross-referencing guidance with explicit requirement markers - Added reference to Anthropic's official best practices - Improved examples showing proper skill reference format ## v3.0.1 (2025-10-16) ### Changes We now use Anthropic's first-party skills system! ## v2.0.2 (2025-10-12) ### Bug Fixes - **Fixed false warning when local skills repo is ahead of upstream** - The initialization script was incorrectly warning "New skills available from upstream" when the local repository had commits ahead of upstream. The logic now correctly distinguishes between three git states: local behind (should update), local ahead (no warning), and diverged (should warn). ## v2.0.1 (2025-10-12) ### Bug Fixes - **Fixed session-start hook execution in plugin context** (#8, PR #9) - The hook was failing silently with "Plugin hook error" preventing skills context from loading. Fixed by: - Using `${BASH_SOURCE[0]:-$0}` fallback when BASH_SOURCE is unbound in Claude Code's execution context - Adding `|| true` to handle empty grep results gracefully when filtering status flags --- # Superpowers v2.0.0 Release Notes ## Overview Superpowers v2.0 makes skills more accessible, maintainable, and community-driven through a major architectural shift. The headline change is **skills repository separation**: all skills, scripts, and documentation have moved from the plugin into a dedicated repository ([obra/superpowers-skills](https://github.com/obra/superpowers-skills)). This transforms superpowers from a monolithic plugin into a lightweight shim that manages a local clone of the skills repository. Skills auto-update on session start. Users fork and contribute improvements via standard git workflows. The skills library versions independently from the plugin. Beyond infrastructure, this release adds nine new skills focused on problem-solving, research, and architecture. We rewrote the core **using-skills** documentation with imperative tone and clearer structure, making it easier for Claude to understand when and how to use skills. **find-skills** now outputs paths you can paste directly into the Read tool, eliminating friction in the skills discovery workflow. Users experience seamless operation: the plugin handles cloning, forking, and updating automatically. Contributors find the new architecture makes improving and sharing skills trivial. This release lays the foundation for skills to evolve rapidly as a community resource. ## Breaking Changes ### Skills Repository Separation **The biggest change:** Skills no longer live in the plugin. They've been moved to a separate repository at [obra/superpowers-skills](https://github.com/obra/superpowers-skills). **What this means for you:** - **First install:** Plugin automatically clones skills to `~/.config/superpowers/skills/` - **Forking:** During setup, you'll be offered the option to fork the skills repo (if `gh` is installed) - **Updates:** Skills auto-update on session start (fast-forward when possible) - **Contributing:** Work on branches, commit locally, submit PRs to upstream - **No more shadowing:** Old two-tier system (personal/core) replaced with single-repo branch workflow **Migration:** If you have an existing installation: 1. Your old `~/.config/superpowers/.git` will be backed up to `~/.config/superpowers/.git.bak` 2. Old skills will be backed up to `~/.config/superpowers/skills.bak` 3. Fresh clone of obra/superpowers-skills will be created at `~/.config/superpowers/skills/` ### Removed Features - **Personal superpowers overlay system** - Replaced with git branch workflow - **setup-personal-superpowers hook** - Replaced by initialize-skills.sh ## New Features ### Skills Repository Infrastructure **Automatic Clone & Setup** (`lib/initialize-skills.sh`) - Clones obra/superpowers-skills on first run - Offers fork creation if GitHub CLI is installed - Sets up upstream/origin remotes correctly - Handles migration from old installation **Auto-Update** - Fetches from tracking remote on every session start - Auto-merges with fast-forward when possible - Notifies when manual sync needed (branch diverged) - Uses pulling-updates-from-skills-repository skill for manual sync ### New Skills **Problem-Solving Skills** (`skills/problem-solving/`) - **collision-zone-thinking** - Force unrelated concepts together for emergent insights - **inversion-exercise** - Flip assumptions to reveal hidden constraints - **meta-pattern-recognition** - Spot universal principles across domains - **scale-game** - Test at extremes to expose fundamental truths - **simplification-cascades** - Find insights that eliminate multiple components - **when-stuck** - Dispatch to right problem-solving technique **Research Skills** (`skills/research/`) - **tracing-knowledge-lineages** - Understand how ideas evolved over time **Architecture Skills** (`skills/architecture/`) - **preserving-productive-tensions** - Keep multiple valid approaches instead of forcing premature resolution ### Skills Improvements **using-skills (formerly getting-started)** - Renamed from getting-started to using-skills - Complete rewrite with imperative tone (v4.0.0) - Front-loaded critical rules - Added "Why" explanations for all workflows - Always includes /SKILL.md suffix in references - Clearer distinction between rigid rules and flexible patterns **writing-skills** - Cross-referencing guidance moved from using-skills - Added token efficiency section (word count targets) - Improved CSO (Claude Search Optimization) guidance **sharing-skills** - Updated for new branch-and-PR workflow (v2.0.0) - Removed personal/core split references **pulling-updates-from-skills-repository** (new) - Complete workflow for syncing with upstream - Replaces old "updating-skills" skill ### Tools Improvements **find-skills** - Now outputs full paths with /SKILL.md suffix - Makes paths directly usable with Read tool - Updated help text **skill-run** - Moved from scripts/ to skills/using-skills/ - Improved documentation ### Plugin Infrastructure **Session Start Hook** - Now loads from skills repository location - Shows full skills list at session start - Prints skills location info - Shows update status (updated successfully / behind upstream) - Moved "skills behind" warning to end of output **Environment Variables** - `SUPERPOWERS_SKILLS_ROOT` set to `~/.config/superpowers/skills` - Used consistently throughout all paths ## Bug Fixes - Fixed duplicate upstream remote addition when forking - Fixed find-skills double "skills/" prefix in output - Removed obsolete setup-personal-superpowers call from session-start - Fixed path references throughout hooks and commands ## Documentation ### README - Updated for new skills repository architecture - Prominent link to superpowers-skills repo - Updated auto-update description - Fixed skill names and references - Updated Meta skills list ### Testing Documentation - Added comprehensive testing checklist (`docs/TESTING-CHECKLIST.md`) - Created local marketplace config for testing - Documented manual testing scenarios ## Technical Details ### File Changes **Added:** - `lib/initialize-skills.sh` - Skills repo initialization and auto-update - `docs/TESTING-CHECKLIST.md` - Manual testing scenarios - `.claude-plugin/marketplace.json` - Local testing config **Removed:** - `skills/` directory (82 files) - Now in obra/superpowers-skills - `scripts/` directory - Now in obra/superpowers-skills/skills/using-skills/ - `hooks/setup-personal-superpowers.sh` - Obsolete **Modified:** - `hooks/session-start.sh` - Use skills from ~/.config/superpowers/skills - `commands/brainstorm.md` - Updated paths to SUPERPOWERS_SKILLS_ROOT - `commands/write-plan.md` - Updated paths to SUPERPOWERS_SKILLS_ROOT - `commands/execute-plan.md` - Updated paths to SUPERPOWERS_SKILLS_ROOT - `README.md` - Complete rewrite for new architecture ### Commit History This release includes: - 20+ commits for skills repository separation - PR #1: Amplifier-inspired problem-solving and research skills - PR #2: Personal superpowers overlay system (later replaced) - Multiple skill refinements and documentation improvements ## Upgrade Instructions ### Fresh Install ```bash # In Claude Code /plugin marketplace add obra/superpowers-marketplace /plugin install superpowers@superpowers-marketplace ``` The plugin handles everything automatically. ### Upgrading from v1.x 1. **Backup your personal skills** (if you have any): ```bash cp -r ~/.config/superpowers/skills ~/superpowers-skills-backup ``` 2. **Update the plugin:** ```bash /plugin update superpowers ``` 3. **On next session start:** - Old installation will be backed up automatically - Fresh skills repo will be cloned - If you have GitHub CLI, you'll be offered the option to fork 4. **Migrate personal skills** (if you had any): - Create a branch in your local skills repo - Copy your personal skills from backup - Commit and push to your fork - Consider contributing back via PR ## What's Next ### For Users - Explore the new problem-solving skills - Try the branch-based workflow for skill improvements - Contribute skills back to the community ### For Contributors - Skills repository is now at https://github.com/obra/superpowers-skills - Fork → Branch → PR workflow - See skills/meta/writing-skills/SKILL.md for TDD approach to documentation ## Known Issues None at this time. ## Credits - Problem-solving skills inspired by Amplifier patterns - Community contributions and feedback - Extensive testing and iteration on skill effectiveness --- **Full Changelog:** https://github.com/obra/superpowers/compare/dd013f6...main **Skills Repository:** https://github.com/obra/superpowers-skills **Issues:** https://github.com/obra/superpowers/issues ================================================ FILE: agents/code-reviewer.md ================================================ --- name: code-reviewer description: | Use this agent when a major project step has been completed and needs to be reviewed against the original plan and coding standards. Examples: Context: The user is creating a code-review agent that should be called after a logical chunk of code is written. user: "I've finished implementing the user authentication system as outlined in step 3 of our plan" assistant: "Great work! Now let me use the code-reviewer agent to review the implementation against our plan and coding standards" Since a major project step has been completed, use the code-reviewer agent to validate the work against the plan and identify any issues. Context: User has completed a significant feature implementation. user: "The API endpoints for the task management system are now complete - that covers step 2 from our architecture document" assistant: "Excellent! Let me have the code-reviewer agent examine this implementation to ensure it aligns with our plan and follows best practices" A numbered step from the planning document has been completed, so the code-reviewer agent should review the work. model: inherit --- You are a Senior Code Reviewer with expertise in software architecture, design patterns, and best practices. Your role is to review completed project steps against original plans and ensure code quality standards are met. When reviewing completed work, you will: 1. **Plan Alignment Analysis**: - Compare the implementation against the original planning document or step description - Identify any deviations from the planned approach, architecture, or requirements - Assess whether deviations are justified improvements or problematic departures - Verify that all planned functionality has been implemented 2. **Code Quality Assessment**: - Review code for adherence to established patterns and conventions - Check for proper error handling, type safety, and defensive programming - Evaluate code organization, naming conventions, and maintainability - Assess test coverage and quality of test implementations - Look for potential security vulnerabilities or performance issues 3. **Architecture and Design Review**: - Ensure the implementation follows SOLID principles and established architectural patterns - Check for proper separation of concerns and loose coupling - Verify that the code integrates well with existing systems - Assess scalability and extensibility considerations 4. **Documentation and Standards**: - Verify that code includes appropriate comments and documentation - Check that file headers, function documentation, and inline comments are present and accurate - Ensure adherence to project-specific coding standards and conventions 5. **Issue Identification and Recommendations**: - Clearly categorize issues as: Critical (must fix), Important (should fix), or Suggestions (nice to have) - For each issue, provide specific examples and actionable recommendations - When you identify plan deviations, explain whether they're problematic or beneficial - Suggest specific improvements with code examples when helpful 6. **Communication Protocol**: - If you find significant deviations from the plan, ask the coding agent to review and confirm the changes - If you identify issues with the original plan itself, recommend plan updates - For implementation problems, provide clear guidance on fixes needed - Always acknowledge what was done well before highlighting issues Your output should be structured, actionable, and focused on helping maintain high code quality while ensuring project goals are met. Be thorough but concise, and always provide constructive feedback that helps improve both the current implementation and future development practices. ================================================ FILE: commands/brainstorm.md ================================================ --- description: "Deprecated - use the superpowers:brainstorming skill instead" --- Tell your human partner that this command is deprecated and will be removed in the next major release. They should ask you to use the "superpowers brainstorming" skill instead. ================================================ FILE: commands/execute-plan.md ================================================ --- description: "Deprecated - use the superpowers:executing-plans skill instead" --- Tell your human partner that this command is deprecated and will be removed in the next major release. They should ask you to use the "superpowers executing-plans" skill instead. ================================================ FILE: commands/write-plan.md ================================================ --- description: "Deprecated - use the superpowers:writing-plans skill instead" --- Tell your human partner that this command is deprecated and will be removed in the next major release. They should ask you to use the "superpowers writing-plans" skill instead. ================================================ FILE: docs/README.codex.md ================================================ # Superpowers for Codex Guide for using Superpowers with OpenAI Codex via native skill discovery. ## Quick Install Tell Codex: ``` Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md ``` ## Manual Installation ### Prerequisites - OpenAI Codex CLI - Git ### Steps 1. Clone the repo: ```bash git clone https://github.com/obra/superpowers.git ~/.codex/superpowers ``` 2. Create the skills symlink: ```bash mkdir -p ~/.agents/skills ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers ``` 3. Restart Codex. 4. **For subagent skills** (optional): Skills like `dispatching-parallel-agents` and `subagent-driven-development` require Codex's multi-agent feature. Add to your Codex config: ```toml [features] multi_agent = true ``` ### Windows Use a junction instead of a symlink (works without Developer Mode): ```powershell New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills" cmd /c mklink /J "$env:USERPROFILE\.agents\skills\superpowers" "$env:USERPROFILE\.codex\superpowers\skills" ``` ## How It Works Codex has native skill discovery — it scans `~/.agents/skills/` at startup, parses SKILL.md frontmatter, and loads skills on demand. Superpowers skills are made visible through a single symlink: ``` ~/.agents/skills/superpowers/ → ~/.codex/superpowers/skills/ ``` The `using-superpowers` skill is discovered automatically and enforces skill usage discipline — no additional configuration needed. ## Usage Skills are discovered automatically. Codex activates them when: - You mention a skill by name (e.g., "use brainstorming") - The task matches a skill's description - The `using-superpowers` skill directs Codex to use one ### Personal Skills Create your own skills in `~/.agents/skills/`: ```bash mkdir -p ~/.agents/skills/my-skill ``` Create `~/.agents/skills/my-skill/SKILL.md`: ```markdown --- name: my-skill description: Use when [condition] - [what it does] --- # My Skill [Your skill content here] ``` The `description` field is how Codex decides when to activate a skill automatically — write it as a clear trigger condition. ## Updating ```bash cd ~/.codex/superpowers && git pull ``` Skills update instantly through the symlink. ## Uninstalling ```bash rm ~/.agents/skills/superpowers ``` **Windows (PowerShell):** ```powershell Remove-Item "$env:USERPROFILE\.agents\skills\superpowers" ``` Optionally delete the clone: `rm -rf ~/.codex/superpowers` (Windows: `Remove-Item -Recurse -Force "$env:USERPROFILE\.codex\superpowers"`). ## Troubleshooting ### Skills not showing up 1. Verify the symlink: `ls -la ~/.agents/skills/superpowers` 2. Check skills exist: `ls ~/.codex/superpowers/skills` 3. Restart Codex — skills are discovered at startup ### Windows junction issues Junctions normally work without special permissions. If creation fails, try running PowerShell as administrator. ## Getting Help - Report issues: https://github.com/obra/superpowers/issues - Main documentation: https://github.com/obra/superpowers ================================================ FILE: docs/README.opencode.md ================================================ # Superpowers for OpenCode Complete guide for using Superpowers with [OpenCode.ai](https://opencode.ai). ## Installation Add superpowers to the `plugin` array in your `opencode.json` (global or project-level): ```json { "plugin": ["superpowers@git+https://github.com/obra/superpowers.git"] } ``` Restart OpenCode. The plugin auto-installs via Bun and registers all skills automatically. Verify by asking: "Tell me about your superpowers" ### Migrating from the old symlink-based install If you previously installed superpowers using `git clone` and symlinks, remove the old setup: ```bash # Remove old symlinks rm -f ~/.config/opencode/plugins/superpowers.js rm -rf ~/.config/opencode/skills/superpowers # Optionally remove the cloned repo rm -rf ~/.config/opencode/superpowers # Remove skills.paths from opencode.json if you added one for superpowers ``` Then follow the installation steps above. ## Usage ### Finding Skills Use OpenCode's native `skill` tool to list all available skills: ``` use skill tool to list skills ``` ### Loading a Skill ``` use skill tool to load superpowers/brainstorming ``` ### Personal Skills Create your own skills in `~/.config/opencode/skills/`: ```bash mkdir -p ~/.config/opencode/skills/my-skill ``` Create `~/.config/opencode/skills/my-skill/SKILL.md`: ```markdown --- name: my-skill description: Use when [condition] - [what it does] --- # My Skill [Your skill content here] ``` ### Project Skills Create project-specific skills in `.opencode/skills/` within your project. **Skill Priority:** Project skills > Personal skills > Superpowers skills ## Updating Superpowers updates automatically when you restart OpenCode. The plugin is re-installed from the git repository on each launch. To pin a specific version, use a branch or tag: ```json { "plugin": ["superpowers@git+https://github.com/obra/superpowers.git#v5.0.3"] } ``` ## How It Works The plugin does two things: 1. **Injects bootstrap context** via the `experimental.chat.system.transform` hook, adding superpowers awareness to every conversation. 2. **Registers the skills directory** via the `config` hook, so OpenCode discovers all superpowers skills without symlinks or manual config. ### Tool Mapping Skills written for Claude Code are automatically adapted for OpenCode: - `TodoWrite` → `todowrite` - `Task` with subagents → OpenCode's `@mention` system - `Skill` tool → OpenCode's native `skill` tool - File operations → Native OpenCode tools ## Troubleshooting ### Plugin not loading 1. Check OpenCode logs: `opencode run --print-logs "hello" 2>&1 | grep -i superpowers` 2. Verify the plugin line in your `opencode.json` is correct 3. Make sure you're running a recent version of OpenCode ### Skills not found 1. Use OpenCode's `skill` tool to list available skills 2. Check that the plugin is loading (see above) 3. Each skill needs a `SKILL.md` file with valid YAML frontmatter ### Bootstrap not appearing 1. Check OpenCode version supports `experimental.chat.system.transform` hook 2. Restart OpenCode after config changes ## Getting Help - Report issues: https://github.com/obra/superpowers/issues - Main documentation: https://github.com/obra/superpowers - OpenCode docs: https://opencode.ai/docs/ ================================================ FILE: docs/plans/2025-11-22-opencode-support-design.md ================================================ # OpenCode Support Design **Date:** 2025-11-22 **Author:** Bot & Jesse **Status:** Design Complete, Awaiting Implementation ## Overview Add full superpowers support for OpenCode.ai using a native OpenCode plugin architecture that shares core functionality with the existing Codex implementation. ## Background OpenCode.ai is a coding agent similar to Claude Code and Codex. Previous attempts to port superpowers to OpenCode (PR #93, PR #116) used file-copying approaches. This design takes a different approach: building a native OpenCode plugin using their JavaScript/TypeScript plugin system while sharing code with the Codex implementation. ### Key Differences Between Platforms - **Claude Code**: Native Anthropic plugin system + file-based skills - **Codex**: No plugin system → bootstrap markdown + CLI script - **OpenCode**: JavaScript/TypeScript plugins with event hooks and custom tools API ### OpenCode's Agent System - **Primary agents**: Build (default, full access) and Plan (restricted, read-only) - **Subagents**: General (research, searching, multi-step tasks) - **Invocation**: Automatic dispatch by primary agents OR manual `@mention` syntax - **Configuration**: Custom agents in `opencode.json` or `~/.config/opencode/agent/` ## Architecture ### High-Level Structure 1. **Shared Core Module** (`lib/skills-core.js`) - Common skill discovery and parsing logic - Used by both Codex and OpenCode implementations 2. **Platform-Specific Wrappers** - Codex: CLI script (`.codex/superpowers-codex`) - OpenCode: Plugin module (`.opencode/plugin/superpowers.js`) 3. **Skill Directories** - Core: `~/.config/opencode/superpowers/skills/` (or installed location) - Personal: `~/.config/opencode/skills/` (shadows core skills) ### Code Reuse Strategy Extract common functionality from `.codex/superpowers-codex` into shared module: ```javascript // lib/skills-core.js module.exports = { extractFrontmatter(filePath), // Parse name + description from YAML findSkillsInDir(dir, maxDepth), // Recursive SKILL.md discovery findAllSkills(dirs), // Scan multiple directories resolveSkillPath(skillName, dirs), // Handle shadowing (personal > core) checkForUpdates(repoDir) // Git fetch/status check }; ``` ### Skill Frontmatter Format Current format (no `when_to_use` field): ```yaml --- name: skill-name description: Use when [condition] - [what it does]; [additional context] --- ``` ## OpenCode Plugin Implementation ### Custom Tools **Tool 1: `use_skill`** Loads a specific skill's content into the conversation (equivalent to Claude's Skill tool). ```javascript { name: 'use_skill', description: 'Load and read a specific skill to guide your work', schema: z.object({ skill_name: z.string().describe('Name of skill (e.g., "superpowers:brainstorming")') }), execute: async ({ skill_name }) => { const { skillPath, content, frontmatter } = resolveAndReadSkill(skill_name); const skillDir = path.dirname(skillPath); return `# ${frontmatter.name} # ${frontmatter.description} # Supporting tools and docs are in ${skillDir} # ============================================ ${content}`; } } ``` **Tool 2: `find_skills`** Lists all available skills with metadata. ```javascript { name: 'find_skills', description: 'List all available skills', schema: z.object({}), execute: async () => { const skills = discoverAllSkills(); return skills.map(s => `${s.namespace}:${s.name} ${s.description} Directory: ${s.directory} `).join('\n'); } } ``` ### Session Startup Hook When a new session starts (`session.started` event): 1. **Inject using-superpowers content** - Full content of the using-superpowers skill - Establishes mandatory workflows 2. **Run find_skills automatically** - Display full list of available skills upfront - Include skill directories for each 3. **Inject tool mapping instructions** ```markdown **Tool Mapping for OpenCode:** When skills reference tools you don't have, substitute: - `TodoWrite` → `update_plan` - `Task` with subagents → Use OpenCode subagent system (@mention) - `Skill` tool → `use_skill` custom tool - Read, Write, Edit, Bash → Your native equivalents **Skill directories contain:** - Supporting scripts (run with bash) - Additional documentation (read with read tool) - Utilities specific to that skill ``` 4. **Check for updates** (non-blocking) - Quick git fetch with timeout - Notify if updates available ### Plugin Structure ```javascript // .opencode/plugin/superpowers.js const skillsCore = require('../../lib/skills-core'); const path = require('path'); const fs = require('fs'); const { z } = require('zod'); export const SuperpowersPlugin = async ({ client, directory, $ }) => { const superpowersDir = path.join(process.env.HOME, '.config/opencode/superpowers'); const personalDir = path.join(process.env.HOME, '.config/opencode/skills'); return { 'session.started': async () => { const usingSuperpowers = await readSkill('using-superpowers'); const skillsList = await findAllSkills(); const toolMapping = getToolMappingInstructions(); return { context: `${usingSuperpowers}\n\n${skillsList}\n\n${toolMapping}` }; }, tools: [ { name: 'use_skill', description: 'Load and read a specific skill', schema: z.object({ skill_name: z.string() }), execute: async ({ skill_name }) => { // Implementation using skillsCore } }, { name: 'find_skills', description: 'List all available skills', schema: z.object({}), execute: async () => { // Implementation using skillsCore } } ] }; }; ``` ## File Structure ``` superpowers/ ├── lib/ │ └── skills-core.js # NEW: Shared skill logic ├── .codex/ │ ├── superpowers-codex # UPDATED: Use skills-core │ ├── superpowers-bootstrap.md │ └── INSTALL.md ├── .opencode/ │ ├── plugin/ │ │ └── superpowers.js # NEW: OpenCode plugin │ └── INSTALL.md # NEW: Installation guide └── skills/ # Unchanged ``` ## Implementation Plan ### Phase 1: Refactor Shared Core 1. Create `lib/skills-core.js` - Extract frontmatter parsing from `.codex/superpowers-codex` - Extract skill discovery logic - Extract path resolution (with shadowing) - Update to use only `name` and `description` (no `when_to_use`) 2. Update `.codex/superpowers-codex` to use shared core - Import from `../lib/skills-core.js` - Remove duplicated code - Keep CLI wrapper logic 3. Test Codex implementation still works - Verify bootstrap command - Verify use-skill command - Verify find-skills command ### Phase 2: Build OpenCode Plugin 1. Create `.opencode/plugin/superpowers.js` - Import shared core from `../../lib/skills-core.js` - Implement plugin function - Define custom tools (use_skill, find_skills) - Implement session.started hook 2. Create `.opencode/INSTALL.md` - Installation instructions - Directory setup - Configuration guidance 3. Test OpenCode implementation - Verify session startup bootstrap - Verify use_skill tool works - Verify find_skills tool works - Verify skill directories are accessible ### Phase 3: Documentation & Polish 1. Update README with OpenCode support 2. Add OpenCode installation to main docs 3. Update RELEASE-NOTES 4. Test both Codex and OpenCode work correctly ## Next Steps 1. **Create isolated workspace** (using git worktrees) - Branch: `feature/opencode-support` 2. **Follow TDD where applicable** - Test shared core functions - Test skill discovery and parsing - Integration tests for both platforms 3. **Incremental implementation** - Phase 1: Refactor shared core + update Codex - Verify Codex still works before moving on - Phase 2: Build OpenCode plugin - Phase 3: Documentation and polish 4. **Testing strategy** - Manual testing with real OpenCode installation - Verify skill loading, directories, scripts work - Test both Codex and OpenCode side-by-side - Verify tool mappings work correctly 5. **PR and merge** - Create PR with complete implementation - Test in clean environment - Merge to main ## Benefits - **Code reuse**: Single source of truth for skill discovery/parsing - **Maintainability**: Bug fixes apply to both platforms - **Extensibility**: Easy to add future platforms (Cursor, Windsurf, etc.) - **Native integration**: Uses OpenCode's plugin system properly - **Consistency**: Same skill experience across all platforms ================================================ FILE: docs/plans/2025-11-22-opencode-support-implementation.md ================================================ # OpenCode Support Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Add full superpowers support for OpenCode.ai with a native JavaScript plugin that shares core functionality with the existing Codex implementation. **Architecture:** Extract common skill discovery/parsing logic into `lib/skills-core.js`, refactor Codex to use it, then build OpenCode plugin using their native plugin API with custom tools and session hooks. **Tech Stack:** Node.js, JavaScript, OpenCode Plugin API, Git worktrees --- ## Phase 1: Create Shared Core Module ### Task 1: Extract Frontmatter Parsing **Files:** - Create: `lib/skills-core.js` - Reference: `.codex/superpowers-codex` (lines 40-74) **Step 1: Create lib/skills-core.js with extractFrontmatter function** ```javascript #!/usr/bin/env node const fs = require('fs'); const path = require('path'); /** * Extract YAML frontmatter from a skill file. * Current format: * --- * name: skill-name * description: Use when [condition] - [what it does] * --- * * @param {string} filePath - Path to SKILL.md file * @returns {{name: string, description: string}} */ function extractFrontmatter(filePath) { try { const content = fs.readFileSync(filePath, 'utf8'); const lines = content.split('\n'); let inFrontmatter = false; let name = ''; let description = ''; for (const line of lines) { if (line.trim() === '---') { if (inFrontmatter) break; inFrontmatter = true; continue; } if (inFrontmatter) { const match = line.match(/^(\w+):\s*(.*)$/); if (match) { const [, key, value] = match; switch (key) { case 'name': name = value.trim(); break; case 'description': description = value.trim(); break; } } } } return { name, description }; } catch (error) { return { name: '', description: '' }; } } module.exports = { extractFrontmatter }; ``` **Step 2: Verify file was created** Run: `ls -l lib/skills-core.js` Expected: File exists **Step 3: Commit** ```bash git add lib/skills-core.js git commit -m "feat: create shared skills core module with frontmatter parser" ``` --- ### Task 2: Extract Skill Discovery Logic **Files:** - Modify: `lib/skills-core.js` - Reference: `.codex/superpowers-codex` (lines 97-136) **Step 1: Add findSkillsInDir function to skills-core.js** Add before `module.exports`: ```javascript /** * Find all SKILL.md files in a directory recursively. * * @param {string} dir - Directory to search * @param {string} sourceType - 'personal' or 'superpowers' for namespacing * @param {number} maxDepth - Maximum recursion depth (default: 3) * @returns {Array<{path: string, name: string, description: string, sourceType: string}>} */ function findSkillsInDir(dir, sourceType, maxDepth = 3) { const skills = []; if (!fs.existsSync(dir)) return skills; function recurse(currentDir, depth) { if (depth > maxDepth) return; const entries = fs.readdirSync(currentDir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(currentDir, entry.name); if (entry.isDirectory()) { // Check for SKILL.md in this directory const skillFile = path.join(fullPath, 'SKILL.md'); if (fs.existsSync(skillFile)) { const { name, description } = extractFrontmatter(skillFile); skills.push({ path: fullPath, skillFile: skillFile, name: name || entry.name, description: description || '', sourceType: sourceType }); } // Recurse into subdirectories recurse(fullPath, depth + 1); } } } recurse(dir, 0); return skills; } ``` **Step 2: Update module.exports** Replace the exports line with: ```javascript module.exports = { extractFrontmatter, findSkillsInDir }; ``` **Step 3: Verify syntax** Run: `node -c lib/skills-core.js` Expected: No output (success) **Step 4: Commit** ```bash git add lib/skills-core.js git commit -m "feat: add skill discovery function to core module" ``` --- ### Task 3: Extract Skill Resolution Logic **Files:** - Modify: `lib/skills-core.js` - Reference: `.codex/superpowers-codex` (lines 212-280) **Step 1: Add resolveSkillPath function** Add before `module.exports`: ```javascript /** * Resolve a skill name to its file path, handling shadowing * (personal skills override superpowers skills). * * @param {string} skillName - Name like "superpowers:brainstorming" or "my-skill" * @param {string} superpowersDir - Path to superpowers skills directory * @param {string} personalDir - Path to personal skills directory * @returns {{skillFile: string, sourceType: string, skillPath: string} | null} */ function resolveSkillPath(skillName, superpowersDir, personalDir) { // Strip superpowers: prefix if present const forceSuperpowers = skillName.startsWith('superpowers:'); const actualSkillName = forceSuperpowers ? skillName.replace(/^superpowers:/, '') : skillName; // Try personal skills first (unless explicitly superpowers:) if (!forceSuperpowers && personalDir) { const personalPath = path.join(personalDir, actualSkillName); const personalSkillFile = path.join(personalPath, 'SKILL.md'); if (fs.existsSync(personalSkillFile)) { return { skillFile: personalSkillFile, sourceType: 'personal', skillPath: actualSkillName }; } } // Try superpowers skills if (superpowersDir) { const superpowersPath = path.join(superpowersDir, actualSkillName); const superpowersSkillFile = path.join(superpowersPath, 'SKILL.md'); if (fs.existsSync(superpowersSkillFile)) { return { skillFile: superpowersSkillFile, sourceType: 'superpowers', skillPath: actualSkillName }; } } return null; } ``` **Step 2: Update module.exports** ```javascript module.exports = { extractFrontmatter, findSkillsInDir, resolveSkillPath }; ``` **Step 3: Verify syntax** Run: `node -c lib/skills-core.js` Expected: No output **Step 4: Commit** ```bash git add lib/skills-core.js git commit -m "feat: add skill path resolution with shadowing support" ``` --- ### Task 4: Extract Update Check Logic **Files:** - Modify: `lib/skills-core.js` - Reference: `.codex/superpowers-codex` (lines 16-38) **Step 1: Add checkForUpdates function** Add at top after requires: ```javascript const { execSync } = require('child_process'); ``` Add before `module.exports`: ```javascript /** * Check if a git repository has updates available. * * @param {string} repoDir - Path to git repository * @returns {boolean} - True if updates are available */ function checkForUpdates(repoDir) { try { // Quick check with 3 second timeout to avoid delays if network is down const output = execSync('git fetch origin && git status --porcelain=v1 --branch', { cwd: repoDir, timeout: 3000, encoding: 'utf8', stdio: 'pipe' }); // Parse git status output to see if we're behind const statusLines = output.split('\n'); for (const line of statusLines) { if (line.startsWith('## ') && line.includes('[behind ')) { return true; // We're behind remote } } return false; // Up to date } catch (error) { // Network down, git error, timeout, etc. - don't block bootstrap return false; } } ``` **Step 2: Update module.exports** ```javascript module.exports = { extractFrontmatter, findSkillsInDir, resolveSkillPath, checkForUpdates }; ``` **Step 3: Verify syntax** Run: `node -c lib/skills-core.js` Expected: No output **Step 4: Commit** ```bash git add lib/skills-core.js git commit -m "feat: add git update checking to core module" ``` --- ## Phase 2: Refactor Codex to Use Shared Core ### Task 5: Update Codex to Import Shared Core **Files:** - Modify: `.codex/superpowers-codex` (add import at top) **Step 1: Add import statement** After the existing requires at top of file (around line 6), add: ```javascript const skillsCore = require('../lib/skills-core'); ``` **Step 2: Verify syntax** Run: `node -c .codex/superpowers-codex` Expected: No output **Step 3: Commit** ```bash git add .codex/superpowers-codex git commit -m "refactor: import shared skills core in codex" ``` --- ### Task 6: Replace extractFrontmatter with Core Version **Files:** - Modify: `.codex/superpowers-codex` (lines 40-74) **Step 1: Remove local extractFrontmatter function** Delete lines 40-74 (the entire extractFrontmatter function definition). **Step 2: Update all extractFrontmatter calls** Find and replace all calls from `extractFrontmatter(` to `skillsCore.extractFrontmatter(` Affected lines approximately: 90, 310 **Step 3: Verify script still works** Run: `.codex/superpowers-codex find-skills | head -20` Expected: Shows list of skills **Step 4: Commit** ```bash git add .codex/superpowers-codex git commit -m "refactor: use shared extractFrontmatter in codex" ``` --- ### Task 7: Replace findSkillsInDir with Core Version **Files:** - Modify: `.codex/superpowers-codex` (lines 97-136, approximately) **Step 1: Remove local findSkillsInDir function** Delete the entire `findSkillsInDir` function definition (approximately lines 97-136). **Step 2: Update all findSkillsInDir calls** Replace calls from `findSkillsInDir(` to `skillsCore.findSkillsInDir(` **Step 3: Verify script still works** Run: `.codex/superpowers-codex find-skills | head -20` Expected: Shows list of skills **Step 4: Commit** ```bash git add .codex/superpowers-codex git commit -m "refactor: use shared findSkillsInDir in codex" ``` --- ### Task 8: Replace checkForUpdates with Core Version **Files:** - Modify: `.codex/superpowers-codex` (lines 16-38, approximately) **Step 1: Remove local checkForUpdates function** Delete the entire `checkForUpdates` function definition. **Step 2: Update all checkForUpdates calls** Replace calls from `checkForUpdates(` to `skillsCore.checkForUpdates(` **Step 3: Verify script still works** Run: `.codex/superpowers-codex bootstrap | head -50` Expected: Shows bootstrap content **Step 4: Commit** ```bash git add .codex/superpowers-codex git commit -m "refactor: use shared checkForUpdates in codex" ``` --- ## Phase 3: Build OpenCode Plugin ### Task 9: Create OpenCode Plugin Directory Structure **Files:** - Create: `.opencode/plugin/superpowers.js` **Step 1: Create directory** Run: `mkdir -p .opencode/plugin` **Step 2: Create basic plugin file** ```javascript #!/usr/bin/env node /** * Superpowers plugin for OpenCode.ai * * Provides custom tools for loading and discovering skills, * with automatic bootstrap on session start. */ const skillsCore = require('../../lib/skills-core'); const path = require('path'); const fs = require('fs'); const os = require('os'); const homeDir = os.homedir(); const superpowersSkillsDir = path.join(homeDir, '.config/opencode/superpowers/skills'); const personalSkillsDir = path.join(homeDir, '.config/opencode/skills'); /** * OpenCode plugin entry point */ export const SuperpowersPlugin = async ({ project, client, $, directory, worktree }) => { return { // Custom tools and hooks will go here }; }; ``` **Step 3: Verify file was created** Run: `ls -l .opencode/plugin/superpowers.js` Expected: File exists **Step 4: Commit** ```bash git add .opencode/plugin/superpowers.js git commit -m "feat: create opencode plugin scaffold" ``` --- ### Task 10: Implement use_skill Tool **Files:** - Modify: `.opencode/plugin/superpowers.js` **Step 1: Add use_skill tool implementation** Replace the plugin return statement with: ```javascript export const SuperpowersPlugin = async ({ project, client, $, directory, worktree }) => { // Import zod for schema validation const { z } = await import('zod'); return { tools: [ { name: 'use_skill', description: 'Load and read a specific skill to guide your work. Skills contain proven workflows, mandatory processes, and expert techniques.', schema: z.object({ skill_name: z.string().describe('Name of the skill to load (e.g., "superpowers:brainstorming" or "my-custom-skill")') }), execute: async ({ skill_name }) => { // Resolve skill path (handles shadowing: personal > superpowers) const resolved = skillsCore.resolveSkillPath( skill_name, superpowersSkillsDir, personalSkillsDir ); if (!resolved) { return `Error: Skill "${skill_name}" not found.\n\nRun find_skills to see available skills.`; } // Read skill content const fullContent = fs.readFileSync(resolved.skillFile, 'utf8'); const { name, description } = skillsCore.extractFrontmatter(resolved.skillFile); // Extract content after frontmatter const lines = fullContent.split('\n'); let inFrontmatter = false; let frontmatterEnded = false; const contentLines = []; for (const line of lines) { if (line.trim() === '---') { if (inFrontmatter) { frontmatterEnded = true; continue; } inFrontmatter = true; continue; } if (frontmatterEnded || !inFrontmatter) { contentLines.push(line); } } const content = contentLines.join('\n').trim(); const skillDirectory = path.dirname(resolved.skillFile); // Format output similar to Claude Code's Skill tool return `# ${name || skill_name} # ${description || ''} # Supporting tools and docs are in ${skillDirectory} # ============================================ ${content}`; } } ] }; }; ``` **Step 2: Verify syntax** Run: `node -c .opencode/plugin/superpowers.js` Expected: No output **Step 3: Commit** ```bash git add .opencode/plugin/superpowers.js git commit -m "feat: implement use_skill tool for opencode" ``` --- ### Task 11: Implement find_skills Tool **Files:** - Modify: `.opencode/plugin/superpowers.js` **Step 1: Add find_skills tool to tools array** Add after the use_skill tool definition, before closing the tools array: ```javascript { name: 'find_skills', description: 'List all available skills in the superpowers and personal skill libraries.', schema: z.object({}), execute: async () => { // Find skills in both directories const superpowersSkills = skillsCore.findSkillsInDir( superpowersSkillsDir, 'superpowers', 3 ); const personalSkills = skillsCore.findSkillsInDir( personalSkillsDir, 'personal', 3 ); // Combine and format skills list const allSkills = [...personalSkills, ...superpowersSkills]; if (allSkills.length === 0) { return 'No skills found. Install superpowers skills to ~/.config/opencode/superpowers/skills/'; } let output = 'Available skills:\n\n'; for (const skill of allSkills) { const namespace = skill.sourceType === 'personal' ? '' : 'superpowers:'; const skillName = skill.name || path.basename(skill.path); output += `${namespace}${skillName}\n`; if (skill.description) { output += ` ${skill.description}\n`; } output += ` Directory: ${skill.path}\n\n`; } return output; } } ``` **Step 2: Verify syntax** Run: `node -c .opencode/plugin/superpowers.js` Expected: No output **Step 3: Commit** ```bash git add .opencode/plugin/superpowers.js git commit -m "feat: implement find_skills tool for opencode" ``` --- ### Task 12: Implement Session Start Hook **Files:** - Modify: `.opencode/plugin/superpowers.js` **Step 1: Add session.started hook** After the tools array, add: ```javascript 'session.started': async () => { // Read using-superpowers skill content const usingSuperpowersPath = skillsCore.resolveSkillPath( 'using-superpowers', superpowersSkillsDir, personalSkillsDir ); let usingSuperpowersContent = ''; if (usingSuperpowersPath) { const fullContent = fs.readFileSync(usingSuperpowersPath.skillFile, 'utf8'); // Strip frontmatter const lines = fullContent.split('\n'); let inFrontmatter = false; let frontmatterEnded = false; const contentLines = []; for (const line of lines) { if (line.trim() === '---') { if (inFrontmatter) { frontmatterEnded = true; continue; } inFrontmatter = true; continue; } if (frontmatterEnded || !inFrontmatter) { contentLines.push(line); } } usingSuperpowersContent = contentLines.join('\n').trim(); } // Tool mapping instructions const toolMapping = ` **Tool Mapping for OpenCode:** When skills reference tools you don't have, substitute OpenCode equivalents: - \`TodoWrite\` → \`update_plan\` (your planning/task tracking tool) - \`Task\` tool with subagents → Use OpenCode's subagent system (@mention syntax or automatic dispatch) - \`Skill\` tool → \`use_skill\` custom tool (already available) - \`Read\`, \`Write\`, \`Edit\`, \`Bash\` → Use your native tools **Skill directories contain supporting files:** - Scripts you can run with bash tool - Additional documentation you can read - Utilities and helpers specific to that skill **Skills naming:** - Superpowers skills: \`superpowers:skill-name\` (from ~/.config/opencode/superpowers/skills/) - Personal skills: \`skill-name\` (from ~/.config/opencode/skills/) - Personal skills override superpowers skills when names match `; // Check for updates (non-blocking) const hasUpdates = skillsCore.checkForUpdates( path.join(homeDir, '.config/opencode/superpowers') ); const updateNotice = hasUpdates ? '\n\n⚠️ **Updates available!** Run `cd ~/.config/opencode/superpowers && git pull` to update superpowers.' : ''; // Return context to inject into session return { context: ` You have superpowers. **Below is the full content of your 'superpowers:using-superpowers' skill - your introduction to using skills. For all other skills, use the 'use_skill' tool:** ${usingSuperpowersContent} ${toolMapping}${updateNotice} ` }; } ``` **Step 2: Verify syntax** Run: `node -c .opencode/plugin/superpowers.js` Expected: No output **Step 3: Commit** ```bash git add .opencode/plugin/superpowers.js git commit -m "feat: implement session.started hook for opencode" ``` --- ## Phase 4: Documentation ### Task 13: Create OpenCode Installation Guide **Files:** - Create: `.opencode/INSTALL.md` **Step 1: Create installation guide** ```markdown # Installing Superpowers for OpenCode ## Prerequisites - [OpenCode.ai](https://opencode.ai) installed - Node.js installed - Git installed ## Installation Steps ### 1. Install Superpowers Skills ```bash # Clone superpowers skills to OpenCode config directory mkdir -p ~/.config/opencode/superpowers git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers ``` ### 2. Install the Plugin The plugin is included in the superpowers repository you just cloned. OpenCode will automatically discover it from: - `~/.config/opencode/superpowers/.opencode/plugin/superpowers.js` Or you can link it to the project-local plugin directory: ```bash # In your OpenCode project mkdir -p .opencode/plugin ln -s ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js .opencode/plugin/superpowers.js ``` ### 3. Restart OpenCode Restart OpenCode to load the plugin. On the next session, you should see: ``` You have superpowers. ``` ## Usage ### Finding Skills Use the `find_skills` tool to list all available skills: ``` use find_skills tool ``` ### Loading a Skill Use the `use_skill` tool to load a specific skill: ``` use use_skill tool with skill_name: "superpowers:brainstorming" ``` ### Personal Skills Create your own skills in `~/.config/opencode/skills/`: ```bash mkdir -p ~/.config/opencode/skills/my-skill ``` Create `~/.config/opencode/skills/my-skill/SKILL.md`: ```markdown --- name: my-skill description: Use when [condition] - [what it does] --- # My Skill [Your skill content here] ``` Personal skills override superpowers skills with the same name. ## Updating ```bash cd ~/.config/opencode/superpowers git pull ``` ## Troubleshooting ### Plugin not loading 1. Check plugin file exists: `ls ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js` 2. Check OpenCode logs for errors 3. Verify Node.js is installed: `node --version` ### Skills not found 1. Verify skills directory exists: `ls ~/.config/opencode/superpowers/skills` 2. Use `find_skills` tool to see what's discovered 3. Check file structure: each skill should have a `SKILL.md` file ### Tool mapping issues When a skill references a Claude Code tool you don't have: - `TodoWrite` → use `update_plan` - `Task` with subagents → use `@mention` syntax to invoke OpenCode subagents - `Skill` → use `use_skill` tool - File operations → use your native tools ## Getting Help - Report issues: https://github.com/obra/superpowers/issues - Documentation: https://github.com/obra/superpowers ``` **Step 2: Verify file created** Run: `ls -l .opencode/INSTALL.md` Expected: File exists **Step 3: Commit** ```bash git add .opencode/INSTALL.md git commit -m "docs: add opencode installation guide" ``` --- ### Task 14: Update Main README **Files:** - Modify: `README.md` **Step 1: Add OpenCode section** Find the section about supported platforms (search for "Codex" in the file), and add after it: ```markdown ### OpenCode Superpowers works with [OpenCode.ai](https://opencode.ai) through a native JavaScript plugin. **Installation:** See [.opencode/INSTALL.md](.opencode/INSTALL.md) **Features:** - Custom tools: `use_skill` and `find_skills` - Automatic session bootstrap - Personal skills with shadowing - Supporting files and scripts access ``` **Step 2: Verify formatting** Run: `grep -A 10 "### OpenCode" README.md` Expected: Shows the section you added **Step 3: Commit** ```bash git add README.md git commit -m "docs: add opencode support to readme" ``` --- ### Task 15: Update Release Notes **Files:** - Modify: `RELEASE-NOTES.md` **Step 1: Add entry for OpenCode support** At the top of the file (after the header), add: ```markdown ## [Unreleased] ### Added - **OpenCode Support**: Native JavaScript plugin for OpenCode.ai - Custom tools: `use_skill` and `find_skills` - Automatic session bootstrap with tool mapping instructions - Shared core module (`lib/skills-core.js`) for code reuse - Installation guide in `.opencode/INSTALL.md` ### Changed - **Refactored Codex Implementation**: Now uses shared `lib/skills-core.js` module - Eliminates code duplication between Codex and OpenCode - Single source of truth for skill discovery and parsing --- ``` **Step 2: Verify formatting** Run: `head -30 RELEASE-NOTES.md` Expected: Shows your new section **Step 3: Commit** ```bash git add RELEASE-NOTES.md git commit -m "docs: add opencode support to release notes" ``` --- ## Phase 5: Final Verification ### Task 16: Test Codex Still Works **Files:** - Test: `.codex/superpowers-codex` **Step 1: Test find-skills command** Run: `.codex/superpowers-codex find-skills | head -20` Expected: Shows list of skills with names and descriptions **Step 2: Test use-skill command** Run: `.codex/superpowers-codex use-skill superpowers:brainstorming | head -20` Expected: Shows brainstorming skill content **Step 3: Test bootstrap command** Run: `.codex/superpowers-codex bootstrap | head -30` Expected: Shows bootstrap content with instructions **Step 4: If all tests pass, record success** No commit needed - this is verification only. --- ### Task 17: Verify File Structure **Files:** - Check: All new files exist **Step 1: Verify all files created** Run: ```bash ls -l lib/skills-core.js ls -l .opencode/plugin/superpowers.js ls -l .opencode/INSTALL.md ``` Expected: All files exist **Step 2: Verify directory structure** Run: `tree -L 2 .opencode/` (or `find .opencode -type f` if tree not available) Expected: ``` .opencode/ ├── INSTALL.md └── plugin/ └── superpowers.js ``` **Step 3: If structure correct, proceed** No commit needed - this is verification only. --- ### Task 18: Final Commit and Summary **Files:** - Check: `git status` **Step 1: Check git status** Run: `git status` Expected: Working tree clean, all changes committed **Step 2: Review commit log** Run: `git log --oneline -20` Expected: Shows all commits from this implementation **Step 3: Create summary document** Create a completion summary showing: - Total commits made - Files created: `lib/skills-core.js`, `.opencode/plugin/superpowers.js`, `.opencode/INSTALL.md` - Files modified: `.codex/superpowers-codex`, `README.md`, `RELEASE-NOTES.md` - Testing performed: Codex commands verified - Ready for: Testing with actual OpenCode installation **Step 4: Report completion** Present summary to user and offer to: 1. Push to remote 2. Create pull request 3. Test with real OpenCode installation (requires OpenCode installed) --- ## Testing Guide (Manual - Requires OpenCode) These steps require OpenCode to be installed and are not part of the automated implementation: 1. **Install skills**: Follow `.opencode/INSTALL.md` 2. **Start OpenCode session**: Verify bootstrap appears 3. **Test find_skills**: Should list all available skills 4. **Test use_skill**: Load a skill and verify content appears 5. **Test supporting files**: Verify skill directory paths are accessible 6. **Test personal skills**: Create a personal skill and verify it shadows core 7. **Test tool mapping**: Verify TodoWrite → update_plan mapping works ## Success Criteria - [ ] `lib/skills-core.js` created with all core functions - [ ] `.codex/superpowers-codex` refactored to use shared core - [ ] Codex commands still work (find-skills, use-skill, bootstrap) - [ ] `.opencode/plugin/superpowers.js` created with tools and hooks - [ ] Installation guide created - [ ] README and RELEASE-NOTES updated - [ ] All changes committed - [ ] Working tree clean ================================================ FILE: docs/plans/2025-11-28-skills-improvements-from-user-feedback.md ================================================ # Skills Improvements from User Feedback **Date:** 2025-11-28 **Status:** Draft **Source:** Two Claude instances using superpowers in real development scenarios --- ## Executive Summary Two Claude instances provided detailed feedback from actual development sessions. Their feedback reveals **systematic gaps** in current skills that allowed preventable bugs to ship despite following the skills. **Critical insight:** These are problem reports, not just solution proposals. The problems are real; the solutions need careful evaluation. **Key themes:** 1. **Verification gaps** - We verify operations succeed but not that they achieve intended outcomes 2. **Process hygiene** - Background processes accumulate and interfere across subagents 3. **Context optimization** - Subagents get too much irrelevant information 4. **Self-reflection missing** - No prompt to critique own work before handoff 5. **Mock safety** - Mocks can drift from interfaces without detection 6. **Skill activation** - Skills exist but aren't being read/used --- ## Problems Identified ### Problem 1: Configuration Change Verification Gap **What happened:** - Subagent tested "OpenAI integration" - Set `OPENAI_API_KEY` env var - Got status 200 responses - Reported "OpenAI integration working" - **BUT** response contained `"model": "claude-sonnet-4-20250514"` - was actually using Anthropic **Root cause:** `verification-before-completion` checks operations succeed but not that outcomes reflect intended configuration changes. **Impact:** High - False confidence in integration tests, bugs ship to production **Example failure pattern:** - Switch LLM provider → verify status 200 but don't check model name - Enable feature flag → verify no errors but don't check feature is active - Change environment → verify deployment succeeds but don't check environment vars --- ### Problem 2: Background Process Accumulation **What happened:** - Multiple subagents dispatched during session - Each started background server processes - Processes accumulated (4+ servers running) - Stale processes still bound to ports - Later E2E test hit stale server with wrong config - Confusing/incorrect test results **Root cause:** Subagents are stateless - don't know about previous subagents' processes. No cleanup protocol. **Impact:** Medium-High - Tests hit wrong server, false passes/failures, debugging confusion --- ### Problem 3: Context Bloat in Subagent Prompts **What happened:** - Standard approach: give subagent full plan file to read - Experiment: give only task + pattern + file + verify command - Result: Faster, more focused, single-attempt completion more common **Root cause:** Subagents waste tokens and attention on irrelevant plan sections. **Impact:** Medium - Slower execution, more failed attempts **What worked:** ``` You are adding a single E2E test to packnplay's test suite. **Your task:** Add `TestE2E_FeaturePrivilegedMode` to `pkg/runner/e2e_test.go` **What to test:** A local devcontainer feature that requests `"privileged": true` in its metadata should result in the container running with `--privileged` flag. **Follow the exact pattern of TestE2E_FeatureOptionValidation** (at the end of the file) **After writing, run:** `go test -v ./pkg/runner -run TestE2E_FeaturePrivilegedMode -timeout 5m` ``` --- ### Problem 4: No Self-Reflection Before Handoff **What happened:** - Added self-reflection prompt: "Look at your work with fresh eyes - what could be better?" - Implementer for Task 5 identified failing test was due to implementation bug, not test bug - Traced to line 99: `strings.Join(metadata.Entrypoint, " ")` creating invalid Docker syntax - Without self-reflection, would have just reported "test fails" without root cause **Root cause:** Implementers don't naturally step back and critique their own work before reporting completion. **Impact:** Medium - Bugs handed off to reviewer that implementer could have caught --- ### Problem 5: Mock-Interface Drift **What happened:** ```typescript // Interface defines close() interface PlatformAdapter { close(): Promise; } // Code (BUGGY) calls cleanup() await adapter.cleanup(); // Mock (MATCHES BUG) defines cleanup() vi.mock('web-adapter', () => ({ WebAdapter: vi.fn().mockImplementation(() => ({ cleanup: vi.fn().mockResolvedValue(undefined), // Wrong! })), })); ``` - Tests passed - Runtime crashed: "adapter.cleanup is not a function" **Root cause:** Mock derived from what buggy code calls, not from interface definition. TypeScript can't catch inline mocks with wrong method names. **Impact:** High - Tests give false confidence, runtime crashes **Why testing-anti-patterns didn't prevent this:** The skill covers testing mock behavior and mocking without understanding, but not the specific pattern of "derive mock from interface, not implementation." --- ### Problem 6: Code Reviewer File Access **What happened:** - Code reviewer subagent dispatched - Couldn't find test file: "The file doesn't appear to exist in the repository" - File actually exists - Reviewer didn't know to explicitly read it first **Root cause:** Reviewer prompts don't include explicit file reading instructions. **Impact:** Low-Medium - Reviews fail or incomplete --- ### Problem 7: Fix Workflow Latency **What happened:** - Implementer identifies bug during self-reflection - Implementer knows the fix - Current workflow: report → I dispatch fixer → fixer fixes → I verify - Extra round-trip adds latency without adding value **Root cause:** Rigid separation between implementer and fixer roles when implementer has already diagnosed. **Impact:** Low - Latency, but no correctness issue --- ### Problem 8: Skills Not Being Read **What happened:** - `testing-anti-patterns` skill exists - Neither human nor subagents read it before writing tests - Would have prevented some issues (though not all - see Problem 5) **Root cause:** No enforcement that subagents read relevant skills. No prompt includes skill reading. **Impact:** Medium - Skill investment wasted if not used --- ## Proposed Improvements ### 1. verification-before-completion: Add Configuration Change Verification **Add new section:** ```markdown ## Verifying Configuration Changes When testing changes to configuration, providers, feature flags, or environment: **Don't just verify the operation succeeded. Verify the output reflects the intended change.** ### Common Failure Pattern Operation succeeds because *some* valid config exists, but it's not the config you intended to test. ### Examples | Change | Insufficient | Required | |--------|-------------|----------| | Switch LLM provider | Status 200 | Response contains expected model name | | Enable feature flag | No errors | Feature behavior actually active | | Change environment | Deploy succeeds | Logs/vars reference new environment | | Set credentials | Auth succeeds | Authenticated user/context is correct | ### Gate Function ``` BEFORE claiming configuration change works: 1. IDENTIFY: What should be DIFFERENT after this change? 2. LOCATE: Where is that difference observable? - Response field (model name, user ID) - Log line (environment, provider) - Behavior (feature active/inactive) 3. RUN: Command that shows the observable difference 4. VERIFY: Output contains expected difference 5. ONLY THEN: Claim configuration change works Red flags: - "Request succeeded" without checking content - Checking status code but not response body - Verifying no errors but not positive confirmation ``` **Why this works:** Forces verification of INTENT, not just operation success. --- ### 2. subagent-driven-development: Add Process Hygiene for E2E Tests **Add new section:** ```markdown ## Process Hygiene for E2E Tests When dispatching subagents that start services (servers, databases, message queues): ### Problem Subagents are stateless - they don't know about processes started by previous subagents. Background processes persist and can interfere with later tests. ### Solution **Before dispatching E2E test subagent, include cleanup in prompt:** ``` BEFORE starting any services: 1. Kill existing processes: pkill -f "" 2>/dev/null || true 2. Wait for cleanup: sleep 1 3. Verify port free: lsof -i : && echo "ERROR: Port still in use" || echo "Port free" AFTER tests complete: 1. Kill the process you started 2. Verify cleanup: pgrep -f "" || echo "Cleanup successful" ``` ### Example ``` Task: Run E2E test of API server Prompt includes: "Before starting the server: - Kill any existing servers: pkill -f 'node.*server.js' 2>/dev/null || true - Verify port 3001 is free: lsof -i :3001 && exit 1 || echo 'Port available' After tests: - Kill the server you started - Verify: pgrep -f 'node.*server.js' || echo 'Cleanup verified'" ``` ### Why This Matters - Stale processes serve requests with wrong config - Port conflicts cause silent failures - Process accumulation slows system - Confusing test results (hitting wrong server) ``` **Trade-off analysis:** - Adds boilerplate to prompts - But prevents very confusing debugging - Worth it for E2E test subagents --- ### 3. subagent-driven-development: Add Lean Context Option **Modify Step 2: Execute Task with Subagent** **Before:** ``` Read that task carefully from [plan-file]. ``` **After:** ``` ## Context Approaches **Full Plan (default):** Use when tasks are complex or have dependencies: ``` Read Task N from [plan-file] carefully. ``` **Lean Context (for independent tasks):** Use when task is standalone and pattern-based: ``` You are implementing: [1-2 sentence task description] File to modify: [exact path] Pattern to follow: [reference to existing function/test] What to implement: [specific requirement] Verification: [exact command to run] [Do NOT include full plan file] ``` **Use lean context when:** - Task follows existing pattern (add similar test, implement similar feature) - Task is self-contained (doesn't need context from other tasks) - Pattern reference is sufficient (e.g., "follow TestE2E_FeatureOptionValidation") **Use full plan when:** - Task has dependencies on other tasks - Requires understanding of overall architecture - Complex logic that needs context ``` **Example:** ``` Lean context prompt: "You are adding a test for privileged mode in devcontainer features. File: pkg/runner/e2e_test.go Pattern: Follow TestE2E_FeatureOptionValidation (at end of file) Test: Feature with `"privileged": true` in metadata results in `--privileged` flag Verify: go test -v ./pkg/runner -run TestE2E_FeaturePrivilegedMode -timeout 5m Report: Implementation, test results, any issues." ``` **Why this works:** Reduces token usage, increases focus, faster completion when appropriate. --- ### 4. subagent-driven-development: Add Self-Reflection Step **Modify Step 2: Execute Task with Subagent** **Add to prompt template:** ``` When done, BEFORE reporting back: Take a step back and review your work with fresh eyes. Ask yourself: - Does this actually solve the task as specified? - Are there edge cases I didn't consider? - Did I follow the pattern correctly? - If tests are failing, what's the ROOT CAUSE (implementation bug vs test bug)? - What could be better about this implementation? If you identify issues during this reflection, fix them now. Then report: - What you implemented - Self-reflection findings (if any) - Test results - Files changed ``` **Why this works:** Catches bugs implementer can find themselves before handoff. Documented case: identified entrypoint bug through self-reflection. **Trade-off:** Adds ~30 seconds per task, but catches issues before review. --- ### 5. requesting-code-review: Add Explicit File Reading **Modify the code-reviewer template:** **Add at the beginning:** ```markdown ## Files to Review BEFORE analyzing, read these files: 1. [List specific files that changed in the diff] 2. [Files referenced by changes but not modified] Use Read tool to load each file. If you cannot find a file: - Check exact path from diff - Try alternate locations - Report: "Cannot locate [path] - please verify file exists" DO NOT proceed with review until you've read the actual code. ``` **Why this works:** Explicit instruction prevents "file not found" issues. --- ### 6. testing-anti-patterns: Add Mock-Interface Drift Anti-Pattern **Add new Anti-Pattern 6:** ```markdown ## Anti-Pattern 6: Mocks Derived from Implementation **The violation:** ```typescript // Code (BUGGY) calls cleanup() await adapter.cleanup(); // Mock (MATCHES BUG) has cleanup() const mock = { cleanup: vi.fn().mockResolvedValue(undefined) }; // Interface (CORRECT) defines close() interface PlatformAdapter { close(): Promise; } ``` **Why this is wrong:** - Mock encodes the bug into the test - TypeScript can't catch inline mocks with wrong method names - Test passes because both code and mock are wrong - Runtime crashes when real object is used **The fix:** ```typescript // ✅ GOOD: Derive mock from interface // Step 1: Open interface definition (PlatformAdapter) // Step 2: List methods defined there (close, initialize, etc.) // Step 3: Mock EXACTLY those methods const mock = { initialize: vi.fn().mockResolvedValue(undefined), close: vi.fn().mockResolvedValue(undefined), // From interface! }; // Now test FAILS because code calls cleanup() which doesn't exist // That failure reveals the bug BEFORE runtime ``` ### Gate Function ``` BEFORE writing any mock: 1. STOP - Do NOT look at the code under test yet 2. FIND: The interface/type definition for the dependency 3. READ: The interface file 4. LIST: Methods defined in the interface 5. MOCK: ONLY those methods with EXACTLY those names 6. DO NOT: Look at what your code calls IF your test fails because code calls something not in mock: ✅ GOOD - The test found a bug in your code Fix the code to call the correct interface method NOT the mock Red flags: - "I'll mock what the code calls" - Copying method names from implementation - Mock written without reading interface - "The test is failing so I'll add this method to the mock" ``` **Detection:** When you see runtime error "X is not a function" and tests pass: 1. Check if X is mocked 2. Compare mock methods to interface methods 3. Look for method name mismatches ``` **Why this works:** Directly addresses the failure pattern from feedback. --- ### 7. subagent-driven-development: Require Skills Reading for Test Subagents **Add to prompt template when task involves testing:** ```markdown BEFORE writing any tests: 1. Read testing-anti-patterns skill: Use Skill tool: superpowers:testing-anti-patterns 2. Apply gate functions from that skill when: - Writing mocks - Adding methods to production classes - Mocking dependencies This is NOT optional. Tests that violate anti-patterns will be rejected in review. ``` **Why this works:** Ensures skills are actually used, not just exist. **Trade-off:** Adds time to each task, but prevents entire classes of bugs. --- ### 8. subagent-driven-development: Allow Implementer to Fix Self-Identified Issues **Modify Step 2:** **Current:** ``` Subagent reports back with summary of work. ``` **Proposed:** ``` Subagent performs self-reflection, then: IF self-reflection identifies fixable issues: 1. Fix the issues 2. Re-run verification 3. Report: "Initial implementation + self-reflection fix" ELSE: Report: "Implementation complete" Include in report: - Self-reflection findings - Whether fixes were applied - Final verification results ``` **Why this works:** Reduces latency when implementer already knows the fix. Documented case: would have saved one round-trip for entrypoint bug. **Trade-off:** Slightly more complex prompt, but faster end-to-end. --- ## Implementation Plan ### Phase 1: High-Impact, Low-Risk (Do First) 1. **verification-before-completion: Configuration change verification** - Clear addition, doesn't change existing content - Addresses high-impact problem (false confidence in tests) - File: `skills/verification-before-completion/SKILL.md` 2. **testing-anti-patterns: Mock-interface drift** - Adds new anti-pattern, doesn't modify existing - Addresses high-impact problem (runtime crashes) - File: `skills/testing-anti-patterns/SKILL.md` 3. **requesting-code-review: Explicit file reading** - Simple addition to template - Fixes concrete problem (reviewers can't find files) - File: `skills/requesting-code-review/SKILL.md` ### Phase 2: Moderate Changes (Test Carefully) 4. **subagent-driven-development: Process hygiene** - Adds new section, doesn't change workflow - Addresses medium-high impact (test reliability) - File: `skills/subagent-driven-development/SKILL.md` 5. **subagent-driven-development: Self-reflection** - Changes prompt template (higher risk) - But documented to catch bugs - File: `skills/subagent-driven-development/SKILL.md` 6. **subagent-driven-development: Skills reading requirement** - Adds prompt overhead - But ensures skills are actually used - File: `skills/subagent-driven-development/SKILL.md` ### Phase 3: Optimization (Validate First) 7. **subagent-driven-development: Lean context option** - Adds complexity (two approaches) - Needs validation that it doesn't cause confusion - File: `skills/subagent-driven-development/SKILL.md` 8. **subagent-driven-development: Allow implementer to fix** - Changes workflow (higher risk) - Optimization, not bug fix - File: `skills/subagent-driven-development/SKILL.md` --- ## Open Questions 1. **Lean context approach:** - Should we make it the default for pattern-based tasks? - How do we decide which approach to use? - Risk of being too lean and missing important context? 2. **Self-reflection:** - Will this slow down simple tasks significantly? - Should it only apply to complex tasks? - How do we prevent "reflection fatigue" where it becomes rote? 3. **Process hygiene:** - Should this be in subagent-driven-development or a separate skill? - Does it apply to other workflows beyond E2E tests? - How do we handle cases where process SHOULD persist (dev servers)? 4. **Skills reading enforcement:** - Should we require ALL subagents to read relevant skills? - How do we keep prompts from becoming too long? - Risk of over-documenting and losing focus? --- ## Success Metrics How do we know these improvements work? 1. **Configuration verification:** - Zero instances of "test passed but wrong config was used" - Jesse doesn't say "that's not actually testing what you think" 2. **Process hygiene:** - Zero instances of "test hit wrong server" - No port conflict errors during E2E test runs 3. **Mock-interface drift:** - Zero instances of "tests pass but runtime crashes on missing method" - No method name mismatches between mocks and interfaces 4. **Self-reflection:** - Measurable: Do implementer reports include self-reflection findings? - Qualitative: Do fewer bugs make it to code review? 5. **Skills reading:** - Subagent reports reference skill gate functions - Fewer anti-pattern violations in code review --- ## Risks and Mitigations ### Risk: Prompt Bloat **Problem:** Adding all these requirements makes prompts overwhelming **Mitigation:** - Phase implementation (don't add everything at once) - Make some additions conditional (E2E hygiene only for E2E tests) - Consider templates for different task types ### Risk: Analysis Paralysis **Problem:** Too much reflection/verification slows execution **Mitigation:** - Keep gate functions quick (seconds, not minutes) - Make lean context opt-in initially - Monitor task completion times ### Risk: False Sense of Security **Problem:** Following checklist doesn't guarantee correctness **Mitigation:** - Emphasize gate functions are minimums, not maximums - Keep "use judgment" language in skills - Document that skills catch common failures, not all failures ### Risk: Skill Divergence **Problem:** Different skills give conflicting advice **Mitigation:** - Review changes across all skills for consistency - Document how skills interact (Integration sections) - Test with real scenarios before deployment --- ## Recommendation **Proceed with Phase 1 immediately:** - verification-before-completion: Configuration change verification - testing-anti-patterns: Mock-interface drift - requesting-code-review: Explicit file reading **Test Phase 2 with Jesse before finalizing:** - Get feedback on self-reflection impact - Validate process hygiene approach - Confirm skills reading requirement is worth overhead **Hold Phase 3 pending validation:** - Lean context needs real-world testing - Implementer-fix workflow change needs careful evaluation These changes address real problems documented by users while minimizing risk of making skills worse. ================================================ FILE: docs/plans/2026-01-17-visual-brainstorming.md ================================================ # Visual Brainstorming Companion Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Give Claude a browser-based visual companion for brainstorming sessions - show mockups, prototypes, and interactive choices alongside terminal conversation. **Architecture:** Claude writes HTML to a temp file. A local Node.js server watches that file and serves it with an auto-injected helper library. User interactions flow via WebSocket to server stdout, which Claude sees in background task output. **Tech Stack:** Node.js, Express, ws (WebSocket), chokidar (file watching) --- ## Task 1: Create the Server Foundation **Files:** - Create: `lib/brainstorm-server/index.js` - Create: `lib/brainstorm-server/package.json` **Step 1: Create package.json** ```json { "name": "brainstorm-server", "version": "1.0.0", "description": "Visual brainstorming companion server for Claude Code", "main": "index.js", "dependencies": { "chokidar": "^3.5.3", "express": "^4.18.2", "ws": "^8.14.2" } } ``` **Step 2: Create minimal server that starts** ```javascript const express = require('express'); const http = require('http'); const WebSocket = require('ws'); const chokidar = require('chokidar'); const fs = require('fs'); const path = require('path'); const PORT = process.env.BRAINSTORM_PORT || 3333; const SCREEN_FILE = process.env.BRAINSTORM_SCREEN || '/tmp/brainstorm/screen.html'; const SCREEN_DIR = path.dirname(SCREEN_FILE); // Ensure screen directory exists if (!fs.existsSync(SCREEN_DIR)) { fs.mkdirSync(SCREEN_DIR, { recursive: true }); } // Create default screen if none exists if (!fs.existsSync(SCREEN_FILE)) { fs.writeFileSync(SCREEN_FILE, ` Brainstorm Companion

Brainstorm Companion

Waiting for Claude to push a screen...

`); } const app = express(); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); // Track connected browsers for reload notifications const clients = new Set(); wss.on('connection', (ws) => { clients.add(ws); ws.on('close', () => clients.delete(ws)); ws.on('message', (data) => { // User interaction event - write to stdout for Claude const event = JSON.parse(data.toString()); console.log(JSON.stringify({ type: 'user-event', ...event })); }); }); // Serve current screen with helper.js injected app.get('/', (req, res) => { let html = fs.readFileSync(SCREEN_FILE, 'utf-8'); // Inject helper script before const helperScript = fs.readFileSync(path.join(__dirname, 'helper.js'), 'utf-8'); const injection = ``; if (html.includes('')) { html = html.replace('', `${injection}\n`); } else { html += injection; } res.type('html').send(html); }); // Watch for screen file changes chokidar.watch(SCREEN_FILE).on('change', () => { console.log(JSON.stringify({ type: 'screen-updated', file: SCREEN_FILE })); // Notify all browsers to reload clients.forEach(ws => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'reload' })); } }); }); server.listen(PORT, '127.0.0.1', () => { console.log(JSON.stringify({ type: 'server-started', port: PORT, url: `http://localhost:${PORT}` })); }); ``` **Step 3: Run npm install** Run: `cd lib/brainstorm-server && npm install` Expected: Dependencies installed **Step 4: Test server starts** Run: `cd lib/brainstorm-server && timeout 3 node index.js || true` Expected: See JSON with `server-started` and port info **Step 5: Commit** ```bash git add lib/brainstorm-server/ git commit -m "feat: add brainstorm server foundation" ``` --- ## Task 2: Create the Helper Library **Files:** - Create: `lib/brainstorm-server/helper.js` **Step 1: Create helper.js with event auto-capture** ```javascript (function() { const WS_URL = 'ws://' + window.location.host; let ws = null; let eventQueue = []; function connect() { ws = new WebSocket(WS_URL); ws.onopen = () => { // Send any queued events eventQueue.forEach(e => ws.send(JSON.stringify(e))); eventQueue = []; }; ws.onmessage = (msg) => { const data = JSON.parse(msg.data); if (data.type === 'reload') { window.location.reload(); } }; ws.onclose = () => { // Reconnect after 1 second setTimeout(connect, 1000); }; } function send(event) { event.timestamp = Date.now(); if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify(event)); } else { eventQueue.push(event); } } // Auto-capture clicks on interactive elements document.addEventListener('click', (e) => { const target = e.target.closest('button, a, [data-choice], [role="button"], input[type="submit"]'); if (!target) return; // Don't capture regular link navigation if (target.tagName === 'A' && !target.dataset.choice) return; e.preventDefault(); send({ type: 'click', text: target.textContent.trim(), choice: target.dataset.choice || null, id: target.id || null, className: target.className || null }); }); // Auto-capture form submissions document.addEventListener('submit', (e) => { e.preventDefault(); const form = e.target; const formData = new FormData(form); const data = {}; formData.forEach((value, key) => { data[key] = value; }); send({ type: 'submit', formId: form.id || null, formName: form.name || null, data: data }); }); // Auto-capture input changes (debounced) let inputTimeout = null; document.addEventListener('input', (e) => { const target = e.target; if (!target.matches('input, textarea, select')) return; clearTimeout(inputTimeout); inputTimeout = setTimeout(() => { send({ type: 'input', name: target.name || null, id: target.id || null, value: target.value, inputType: target.type || target.tagName.toLowerCase() }); }, 500); // 500ms debounce }); // Expose for explicit use if needed window.brainstorm = { send: send, choice: (value, metadata = {}) => send({ type: 'choice', value, ...metadata }) }; connect(); })(); ``` **Step 2: Verify helper.js is syntactically valid** Run: `node -c lib/brainstorm-server/helper.js` Expected: No syntax errors **Step 3: Commit** ```bash git add lib/brainstorm-server/helper.js git commit -m "feat: add browser helper library for event capture" ``` --- ## Task 3: Write Tests for the Server **Files:** - Create: `tests/brainstorm-server/server.test.js` - Create: `tests/brainstorm-server/package.json` **Step 1: Create test package.json** ```json { "name": "brainstorm-server-tests", "version": "1.0.0", "scripts": { "test": "node server.test.js" } } ``` **Step 2: Write server tests** ```javascript const { spawn } = require('child_process'); const http = require('http'); const WebSocket = require('ws'); const fs = require('fs'); const path = require('path'); const assert = require('assert'); const SERVER_PATH = path.join(__dirname, '../../lib/brainstorm-server/index.js'); const TEST_PORT = 3334; const TEST_SCREEN = '/tmp/brainstorm-test/screen.html'; // Clean up test directory function cleanup() { if (fs.existsSync(path.dirname(TEST_SCREEN))) { fs.rmSync(path.dirname(TEST_SCREEN), { recursive: true }); } } async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function fetch(url) { return new Promise((resolve, reject) => { http.get(url, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve({ status: res.statusCode, body: data })); }).on('error', reject); }); } async function runTests() { cleanup(); // Start server const server = spawn('node', [SERVER_PATH], { env: { ...process.env, BRAINSTORM_PORT: TEST_PORT, BRAINSTORM_SCREEN: TEST_SCREEN } }); let stdout = ''; server.stdout.on('data', (data) => { stdout += data.toString(); }); server.stderr.on('data', (data) => { console.error('Server stderr:', data.toString()); }); await sleep(1000); // Wait for server to start try { // Test 1: Server starts and outputs JSON console.log('Test 1: Server startup message'); assert(stdout.includes('server-started'), 'Should output server-started'); assert(stdout.includes(TEST_PORT.toString()), 'Should include port'); console.log(' PASS'); // Test 2: GET / returns HTML with helper injected console.log('Test 2: Serves HTML with helper injected'); const res = await fetch(`http://localhost:${TEST_PORT}/`); assert.strictEqual(res.status, 200); assert(res.body.includes('brainstorm'), 'Should include brainstorm content'); assert(res.body.includes('WebSocket'), 'Should have helper.js injected'); console.log(' PASS'); // Test 3: WebSocket connection and event relay console.log('Test 3: WebSocket relays events to stdout'); stdout = ''; // Reset stdout capture const ws = new WebSocket(`ws://localhost:${TEST_PORT}`); await new Promise(resolve => ws.on('open', resolve)); ws.send(JSON.stringify({ type: 'click', text: 'Test Button' })); await sleep(100); assert(stdout.includes('user-event'), 'Should relay user events'); assert(stdout.includes('Test Button'), 'Should include event data'); ws.close(); console.log(' PASS'); // Test 4: File change triggers reload notification console.log('Test 4: File change notifies browsers'); const ws2 = new WebSocket(`ws://localhost:${TEST_PORT}`); await new Promise(resolve => ws2.on('open', resolve)); let gotReload = false; ws2.on('message', (data) => { const msg = JSON.parse(data.toString()); if (msg.type === 'reload') gotReload = true; }); // Modify the screen file fs.writeFileSync(TEST_SCREEN, 'Updated'); await sleep(500); assert(gotReload, 'Should send reload message on file change'); ws2.close(); console.log(' PASS'); console.log('\nAll tests passed!'); } finally { server.kill(); cleanup(); } } runTests().catch(err => { console.error('Test failed:', err); process.exit(1); }); ``` **Step 3: Run tests** Run: `cd tests/brainstorm-server && npm install ws && node server.test.js` Expected: All tests pass **Step 4: Commit** ```bash git add tests/brainstorm-server/ git commit -m "test: add brainstorm server integration tests" ``` --- ## Task 4: Add Visual Companion to Brainstorming Skill **Files:** - Modify: `skills/brainstorming/SKILL.md` - Create: `skills/brainstorming/visual-companion.md` (supporting doc) **Step 1: Create the supporting documentation** Create `skills/brainstorming/visual-companion.md`: ```markdown # Visual Companion Reference ## Starting the Server Run as a background job: ```bash node ${PLUGIN_ROOT}/lib/brainstorm-server/index.js ``` Tell the user: "I've started a visual companion at http://localhost:3333 - open it in a browser." ## Pushing Screens Write HTML to `/tmp/brainstorm/screen.html`. The server watches this file and auto-refreshes the browser. ## Reading User Responses Check the background task output for JSON events: ```json {"type":"user-event","type":"click","text":"Option A","choice":"optionA","timestamp":1234567890} {"type":"user-event","type":"submit","data":{"notes":"My feedback"},"timestamp":1234567891} ``` Event types: - **click**: User clicked button or `data-choice` element - **submit**: User submitted form (includes all form data) - **input**: User typed in field (debounced 500ms) ## HTML Patterns ### Choice Cards ```html
``` ### Interactive Mockup ```html
App Header
Content
``` ### Form with Notes ```html
``` ### Explicit JavaScript ```html ``` ``` **Step 2: Add visual companion section to brainstorming skill** Add after "Key Principles" in `skills/brainstorming/SKILL.md`: ```markdown ## Visual Companion (Optional) When brainstorming involves visual elements - UI mockups, wireframes, interactive prototypes - use the browser-based visual companion. **When to use:** - Presenting UI/UX options that benefit from visual comparison - Showing wireframes or layout options - Gathering structured feedback (ratings, forms) - Prototyping click interactions **How it works:** 1. Start the server as a background job 2. Tell user to open http://localhost:3333 3. Write HTML to `/tmp/brainstorm/screen.html` (auto-refreshes) 4. Check background task output for user interactions The terminal remains the primary conversation interface. The browser is a visual aid. **Reference:** See `visual-companion.md` in this skill directory for HTML patterns and API details. ``` **Step 3: Verify the edits** Run: `grep -A5 "Visual Companion" skills/brainstorming/SKILL.md` Expected: Shows the new section **Step 4: Commit** ```bash git add skills/brainstorming/ git commit -m "feat: add visual companion to brainstorming skill" ``` --- ## Task 5: Add Server to Plugin Ignore (Optional Cleanup) **Files:** - Check if `.gitignore` needs node_modules exclusion for lib/brainstorm-server **Step 1: Check current gitignore** Run: `cat .gitignore 2>/dev/null || echo "No .gitignore"` **Step 2: Add node_modules if needed** If not already present, add: ``` lib/brainstorm-server/node_modules/ ``` **Step 3: Commit if changed** ```bash git add .gitignore git commit -m "chore: ignore brainstorm-server node_modules" ``` --- ## Summary After completing all tasks: 1. **Server** at `lib/brainstorm-server/` - Node.js server that watches HTML file and relays events 2. **Helper library** auto-injected - captures clicks, forms, inputs 3. **Tests** at `tests/brainstorm-server/` - verifies server behavior 4. **Brainstorming skill** updated with visual companion section and `visual-companion.md` reference doc **To use:** 1. Start server as background job: `node lib/brainstorm-server/index.js &` 2. Tell user to open `http://localhost:3333` 3. Write HTML to `/tmp/brainstorm/screen.html` 4. Check task output for user events ================================================ FILE: docs/superpowers/plans/2026-01-22-document-review-system.md ================================================ # Document Review System Implementation Plan > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. **Goal:** Add spec and plan document review loops to the brainstorming and writing-plans skills. **Architecture:** Create reviewer prompt templates in each skill directory. Modify skill files to add review loops after document creation. Use Task tool with general-purpose subagent for reviewer dispatch. **Tech Stack:** Markdown skill files, subagent dispatch via Task tool **Spec:** docs/superpowers/specs/2026-01-22-document-review-system-design.md --- ## Chunk 1: Spec Document Reviewer This chunk adds the spec document reviewer to the brainstorming skill. ### Task 1: Create Spec Document Reviewer Prompt Template **Files:** - Create: `skills/brainstorming/spec-document-reviewer-prompt.md` - [ ] **Step 1:** Create the reviewer prompt template file ```markdown # Spec Document Reviewer Prompt Template Use this template when dispatching a spec document reviewer subagent. **Purpose:** Verify the spec is complete, consistent, and ready for implementation planning. **Dispatch after:** Spec document is written to docs/superpowers/specs/ ``` Task tool (general-purpose): description: "Review spec document" prompt: | You are a spec document reviewer. Verify this spec is complete and ready for planning. **Spec to review:** [SPEC_FILE_PATH] ## What to Check | Category | What to Look For | |----------|------------------| | Completeness | TODOs, placeholders, "TBD", incomplete sections | | Coverage | Missing error handling, edge cases, integration points | | Consistency | Internal contradictions, conflicting requirements | | Clarity | Ambiguous requirements | | YAGNI | Unrequested features, over-engineering | ## CRITICAL Look especially hard for: - Any TODO markers or placeholder text - Sections saying "to be defined later" or "will spec when X is done" - Sections noticeably less detailed than others ## Output Format ## Spec Review **Status:** ✅ Approved | ❌ Issues Found **Issues (if any):** - [Section X]: [specific issue] - [why it matters] **Recommendations (advisory):** - [suggestions that don't block approval] ``` **Reviewer returns:** Status, Issues (if any), Recommendations ``` - [ ] **Step 2:** Verify the file was created correctly Run: `cat skills/brainstorming/spec-document-reviewer-prompt.md | head -20` Expected: Shows the header and purpose section - [ ] **Step 3:** Commit ```bash git add skills/brainstorming/spec-document-reviewer-prompt.md git commit -m "feat: add spec document reviewer prompt template" ``` --- ### Task 2: Add Review Loop to Brainstorming Skill **Files:** - Modify: `skills/brainstorming/SKILL.md` - [ ] **Step 1:** Read the current brainstorming skill Run: `cat skills/brainstorming/SKILL.md` - [ ] **Step 2:** Add the review loop section after "After the Design" Find the "After the Design" section and add a new "Spec Review Loop" section after documentation but before implementation: ```markdown **Spec Review Loop:** After writing the spec document: 1. Dispatch spec-document-reviewer subagent (see spec-document-reviewer-prompt.md) 2. If ❌ Issues Found: - Fix the issues in the spec document - Re-dispatch reviewer - Repeat until ✅ Approved 3. If ✅ Approved: proceed to implementation setup **Review loop guidance:** - Same agent that wrote the spec fixes it (preserves context) - If loop exceeds 5 iterations, surface to human for guidance - Reviewers are advisory - explain disagreements if you believe feedback is incorrect ``` - [ ] **Step 3:** Verify the changes Run: `grep -A 15 "Spec Review Loop" skills/brainstorming/SKILL.md` Expected: Shows the new review loop section - [ ] **Step 4:** Commit ```bash git add skills/brainstorming/SKILL.md git commit -m "feat: add spec review loop to brainstorming skill" ``` --- ## Chunk 2: Plan Document Reviewer This chunk adds the plan document reviewer to the writing-plans skill. ### Task 3: Create Plan Document Reviewer Prompt Template **Files:** - Create: `skills/writing-plans/plan-document-reviewer-prompt.md` - [ ] **Step 1:** Create the reviewer prompt template file ```markdown # Plan Document Reviewer Prompt Template Use this template when dispatching a plan document reviewer subagent. **Purpose:** Verify the plan chunk is complete, matches the spec, and has proper task decomposition. **Dispatch after:** Each plan chunk is written ``` Task tool (general-purpose): description: "Review plan chunk N" prompt: | You are a plan document reviewer. Verify this plan chunk is complete and ready for implementation. **Plan chunk to review:** [PLAN_FILE_PATH] - Chunk N only **Spec for reference:** [SPEC_FILE_PATH] ## What to Check | Category | What to Look For | |----------|------------------| | Completeness | TODOs, placeholders, incomplete tasks, missing steps | | Spec Alignment | Chunk covers relevant spec requirements, no scope creep | | Task Decomposition | Tasks atomic, clear boundaries, steps actionable | | Task Syntax | Checkbox syntax (`- [ ]`) on tasks and steps | | Chunk Size | Each chunk under 1000 lines | ## CRITICAL Look especially hard for: - Any TODO markers or placeholder text - Steps that say "similar to X" without actual content - Incomplete task definitions - Missing verification steps or expected outputs ## Output Format ## Plan Review - Chunk N **Status:** ✅ Approved | ❌ Issues Found **Issues (if any):** - [Task X, Step Y]: [specific issue] - [why it matters] **Recommendations (advisory):** - [suggestions that don't block approval] ``` **Reviewer returns:** Status, Issues (if any), Recommendations ``` - [ ] **Step 2:** Verify the file was created Run: `cat skills/writing-plans/plan-document-reviewer-prompt.md | head -20` Expected: Shows the header and purpose section - [ ] **Step 3:** Commit ```bash git add skills/writing-plans/plan-document-reviewer-prompt.md git commit -m "feat: add plan document reviewer prompt template" ``` --- ### Task 4: Add Review Loop to Writing-Plans Skill **Files:** - Modify: `skills/writing-plans/SKILL.md` - [ ] **Step 1:** Read current skill file Run: `cat skills/writing-plans/SKILL.md` - [ ] **Step 2:** Add chunk-by-chunk review section Add before the "Execution Handoff" section: ```markdown ## Plan Review Loop After completing each chunk of the plan: 1. Dispatch plan-document-reviewer subagent for the current chunk - Provide: chunk content, path to spec document 2. If ❌ Issues Found: - Fix the issues in the chunk - Re-dispatch reviewer for that chunk - Repeat until ✅ Approved 3. If ✅ Approved: proceed to next chunk (or execution handoff if last chunk) **Chunk boundaries:** Use `## Chunk N: ` headings to delimit chunks. Each chunk should be ≤1000 lines and logically self-contained. ``` - [ ] **Step 3:** Update task syntax examples to use checkboxes Change the Task Structure section to show checkbox syntax: ```markdown ### Task N: [Component Name] - [ ] **Step 1:** Write the failing test - File: `tests/path/test.py` ... ``` - [ ] **Step 4:** Verify the review loop section was added Run: `grep -A 15 "Plan Review Loop" skills/writing-plans/SKILL.md` Expected: Shows the new review loop section - [ ] **Step 5:** Verify the task syntax examples were updated Run: `grep -A 5 "Task N:" skills/writing-plans/SKILL.md` Expected: Shows checkbox syntax `### Task N:` - [ ] **Step 6:** Commit ```bash git add skills/writing-plans/SKILL.md git commit -m "feat: add plan review loop and checkbox syntax to writing-plans skill" ``` --- ## Chunk 3: Update Plan Document Header This chunk updates the plan document header template to reference the new checkbox syntax requirements. ### Task 5: Update Plan Header Template in Writing-Plans Skill **Files:** - Modify: `skills/writing-plans/SKILL.md` - [ ] **Step 1:** Read current plan header template Run: `grep -A 20 "Plan Document Header" skills/writing-plans/SKILL.md` - [ ] **Step 2:** Update the header template to reference checkbox syntax The plan header should note that tasks and steps use checkbox syntax. Update the header comment: ```markdown > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Tasks and steps use checkbox (`- [ ]`) syntax for tracking. ``` - [ ] **Step 3:** Verify the change Run: `grep -A 5 "For agentic workers:" skills/writing-plans/SKILL.md` Expected: Shows updated header with checkbox syntax mention - [ ] **Step 4:** Commit ```bash git add skills/writing-plans/SKILL.md git commit -m "docs: update plan header to reference checkbox syntax" ``` ================================================ FILE: docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md ================================================ # Visual Brainstorming Refactor Implementation Plan > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Refactor visual brainstorming from blocking TUI feedback model to non-blocking "Browser Displays, Terminal Commands" architecture. **Architecture:** Browser becomes an interactive display; terminal stays the conversation channel. Server writes user events to a per-screen `.events` file that Claude reads on its next turn. Eliminates `wait-for-feedback.sh` and all `TaskOutput` blocking. **Tech Stack:** Node.js (Express, ws, chokidar), vanilla HTML/CSS/JS **Spec:** `docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md` --- ## File Map | File | Action | Responsibility | |------|--------|---------------| | `lib/brainstorm-server/index.js` | Modify | Server: add `.events` file writing, clear on new screen, replace `wrapInFrame` | | `lib/brainstorm-server/frame-template.html` | Modify | Template: remove feedback footer, add content placeholder + selection indicator | | `lib/brainstorm-server/helper.js` | Modify | Client JS: remove send/feedback functions, narrow to click capture + indicator updates | | `lib/brainstorm-server/wait-for-feedback.sh` | Delete | No longer needed | | `skills/brainstorming/visual-companion.md` | Modify | Skill instructions: rewrite loop to non-blocking flow | | `tests/brainstorm-server/server.test.js` | Modify | Tests: update for new template structure and helper.js API | --- ## Chunk 1: Server, Template, Client, Tests, Skill ### Task 1: Update `frame-template.html` **Files:** - Modify: `lib/brainstorm-server/frame-template.html` - [ ] **Step 1: Remove the feedback footer HTML** Replace the feedback-footer div (lines 227-233) with a selection indicator bar: ```html
Click an option above, then return to the terminal
``` Also replace the default content inside `#claude-content` (lines 220-223) with the content placeholder: ```html
``` - [ ] **Step 2: Replace feedback footer CSS with indicator bar CSS** Remove the `.feedback-footer`, `.feedback-footer label`, `.feedback-row`, and the textarea/button styles within `.feedback-footer` (lines 82-112). Add indicator bar CSS: ```css .indicator-bar { background: var(--bg-secondary); border-top: 1px solid var(--border); padding: 0.5rem 1.5rem; flex-shrink: 0; text-align: center; } .indicator-bar span { font-size: 0.75rem; color: var(--text-secondary); } .indicator-bar .selected-text { color: var(--accent); font-weight: 500; } ``` - [ ] **Step 3: Verify template renders** Run the test suite to check the template still loads: ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` Expected: Tests 1-5 should still pass. Tests 6-8 may fail (expected — they assert old structure). - [ ] **Step 4: Commit** ```bash git add lib/brainstorm-server/frame-template.html git commit -m "Replace feedback footer with selection indicator bar in brainstorm template" ``` --- ### Task 2: Update `index.js` — content injection and `.events` file **Files:** - Modify: `lib/brainstorm-server/index.js` - [ ] **Step 1: Write failing test for `.events` file writing** Add to `tests/brainstorm-server/server.test.js` after Test 4 area — a new test that sends a WebSocket event with a `choice` field and verifies `.events` file is written: ```javascript // Test: Choice events written to .events file console.log('Test: Choice events written to .events file'); const ws3 = new WebSocket(`ws://localhost:${TEST_PORT}`); await new Promise(resolve => ws3.on('open', resolve)); ws3.send(JSON.stringify({ type: 'click', choice: 'a', text: 'Option A' })); await sleep(300); const eventsFile = path.join(TEST_DIR, '.events'); assert(fs.existsSync(eventsFile), '.events file should exist after choice click'); const lines = fs.readFileSync(eventsFile, 'utf-8').trim().split('\n'); const event = JSON.parse(lines[lines.length - 1]); assert.strictEqual(event.choice, 'a', 'Event should contain choice'); assert.strictEqual(event.text, 'Option A', 'Event should contain text'); ws3.close(); console.log(' PASS'); ``` - [ ] **Step 2: Run test to verify it fails** ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` Expected: New test FAILS — `.events` file doesn't exist yet. - [ ] **Step 3: Write failing test for `.events` file clearing on new screen** Add another test: ```javascript // Test: .events cleared on new screen console.log('Test: .events cleared on new screen'); // .events file should still exist from previous test assert(fs.existsSync(path.join(TEST_DIR, '.events')), '.events should exist before new screen'); fs.writeFileSync(path.join(TEST_DIR, 'new-screen.html'), '

New screen

'); await sleep(500); assert(!fs.existsSync(path.join(TEST_DIR, '.events')), '.events should be cleared after new screen'); console.log(' PASS'); ``` - [ ] **Step 4: Run test to verify it fails** ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` Expected: New test FAILS — `.events` not cleared on screen push. - [ ] **Step 5: Implement `.events` file writing in `index.js`** In the WebSocket `message` handler (line 74-77 of `index.js`), after the `console.log`, add: ```javascript // Write user events to .events file for Claude to read if (event.choice) { const eventsFile = path.join(SCREEN_DIR, '.events'); fs.appendFileSync(eventsFile, JSON.stringify(event) + '\n'); } ``` In the chokidar `add` handler (line 104-111), add `.events` clearing: ```javascript if (filePath.endsWith('.html')) { // Clear events from previous screen const eventsFile = path.join(SCREEN_DIR, '.events'); if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile); console.log(JSON.stringify({ type: 'screen-added', file: filePath })); // ... existing reload broadcast } ``` - [ ] **Step 6: Replace `wrapInFrame` with comment placeholder injection** Replace the `wrapInFrame` function (lines 27-32 of `index.js`): ```javascript function wrapInFrame(content) { return frameTemplate.replace('', content); } ``` - [ ] **Step 7: Run all tests** ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` Expected: New `.events` tests PASS. Existing tests may still have failures from old assertions (fixed in Task 4). - [ ] **Step 8: Commit** ```bash git add lib/brainstorm-server/index.js tests/brainstorm-server/server.test.js git commit -m "Add .events file writing and comment-based content injection to brainstorm server" ``` --- ### Task 3: Simplify `helper.js` **Files:** - Modify: `lib/brainstorm-server/helper.js` - [ ] **Step 1: Remove `sendToClaude` function** Delete the `sendToClaude` function (lines 92-106) — the function body and the page takeover HTML. - [ ] **Step 2: Remove `window.send` function** Delete the `window.send` function (lines 120-129) — was tied to the removed Send button. - [ ] **Step 3: Remove form submission and input change handlers** Delete the form submission handler (lines 57-71) and the input change handler (lines 73-89) including the `inputTimeout` variable. - [ ] **Step 4: Remove `pageshow` event listener** Delete the `pageshow` listener we added earlier (no textarea to clear anymore). - [ ] **Step 5: Narrow click handler to `[data-choice]` only** Replace the click handler (lines 36-55) with a narrower version: ```javascript // Capture clicks on choice elements document.addEventListener('click', (e) => { const target = e.target.closest('[data-choice]'); if (!target) return; sendEvent({ type: 'click', text: target.textContent.trim(), choice: target.dataset.choice, id: target.id || null }); }); ``` - [ ] **Step 6: Add indicator bar update on choice click** After the `sendEvent` call in the click handler, add: ```javascript // Update indicator bar const indicator = document.getElementById('indicator-text'); if (indicator) { const label = target.querySelector('h3, .content h3, .card-body h3')?.textContent?.trim() || target.dataset.choice; indicator.innerHTML = '' + label + ' selected — return to terminal to continue'; } ``` - [ ] **Step 7: Remove `sendToClaude` from `window.brainstorm` API** Update the `window.brainstorm` object (lines 132-136) to remove `sendToClaude`: ```javascript window.brainstorm = { send: sendEvent, choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata }) }; ``` - [ ] **Step 8: Run tests** ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` - [ ] **Step 9: Commit** ```bash git add lib/brainstorm-server/helper.js git commit -m "Simplify helper.js: remove feedback functions, narrow to choice capture + indicator" ``` --- ### Task 4: Update tests for new structure **Files:** - Modify: `tests/brainstorm-server/server.test.js` **Note:** Line references below are from the _original_ file. Task 2 inserted new tests earlier in the file, so actual line numbers will be shifted. Find tests by their `console.log` labels (e.g., "Test 5:", "Test 6:"). - [ ] **Step 1: Update Test 5 (full document assertion)** Find the Test 5 assertion `!fullRes.body.includes('feedback-footer')`. Change it to: Full documents should NOT have the indicator bar either (they're served as-is): ```javascript assert(!fullRes.body.includes('indicator-bar') || fullDoc.includes('indicator-bar'), 'Should not wrap full documents in frame template'); ``` - [ ] **Step 2: Update Test 6 (fragment wrapping)** Line 125: Replace `feedback-footer` assertion with indicator bar assertion: ```javascript assert(fragRes.body.includes('indicator-bar'), 'Fragment should get indicator bar from frame'); ``` Also verify content placeholder was replaced (fragment content appears, placeholder comment doesn't): ```javascript assert(!fragRes.body.includes(''), 'Content placeholder should be replaced'); ``` - [ ] **Step 3: Update Test 7 (helper.js API)** Lines 140-142: Update assertions to reflect the new API surface: ```javascript assert(helperContent.includes('toggleSelect'), 'helper.js should define toggleSelect'); assert(helperContent.includes('sendEvent'), 'helper.js should define sendEvent'); assert(helperContent.includes('selectedChoice'), 'helper.js should track selectedChoice'); assert(helperContent.includes('brainstorm'), 'helper.js should expose brainstorm API'); assert(!helperContent.includes('sendToClaude'), 'helper.js should not contain sendToClaude'); ``` - [ ] **Step 4: Replace Test 8 (sendToClaude theming) with indicator bar test** Replace Test 8 (lines 145-149) — `sendToClaude` no longer exists. Test the indicator bar instead: ```javascript // Test 8: Indicator bar uses CSS variables (theme support) console.log('Test 8: Indicator bar uses CSS variables'); const templateContent = fs.readFileSync( path.join(__dirname, '../../lib/brainstorm-server/frame-template.html'), 'utf-8' ); assert(templateContent.includes('indicator-bar'), 'Template should have indicator bar'); assert(templateContent.includes('indicator-text'), 'Template should have indicator text element'); console.log(' PASS'); ``` - [ ] **Step 5: Run full test suite** ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` Expected: ALL tests PASS. - [ ] **Step 6: Commit** ```bash git add tests/brainstorm-server/server.test.js git commit -m "Update brainstorm server tests for new template structure and helper.js API" ``` --- ### Task 5: Delete `wait-for-feedback.sh` **Files:** - Delete: `lib/brainstorm-server/wait-for-feedback.sh` - [ ] **Step 1: Verify no other files import or reference `wait-for-feedback.sh`** Search the codebase: ```bash grep -r "wait-for-feedback" /Users/drewritter/prime-rad/superpowers/ --include="*.js" --include="*.md" --include="*.sh" --include="*.json" ``` Expected references: only `visual-companion.md` (rewritten in Task 6) and possibly release notes (historical, leave as-is). - [ ] **Step 2: Delete the file** ```bash rm lib/brainstorm-server/wait-for-feedback.sh ``` - [ ] **Step 3: Run tests to confirm nothing breaks** ```bash cd /Users/drewritter/prime-rad/superpowers && node tests/brainstorm-server/server.test.js ``` Expected: All tests PASS (no test referenced this file). - [ ] **Step 4: Commit** ```bash git add -u lib/brainstorm-server/wait-for-feedback.sh git commit -m "Delete wait-for-feedback.sh: replaced by .events file" ``` --- ### Task 6: Rewrite `visual-companion.md` **Files:** - Modify: `skills/brainstorming/visual-companion.md` - [ ] **Step 1: Update "How It Works" description (line 18)** Replace the sentence about receiving feedback "as JSON" with: ```markdown The server watches a directory for HTML files and serves the newest one to the browser. You write HTML content, the user sees it in their browser and can click to select options. Selections are recorded to a `.events` file that you read on your next turn. ``` - [ ] **Step 2: Update fragment description (line 20)** Remove "feedback footer" from the description of what the frame template provides: ```markdown **Content fragments vs full documents:** If your HTML file starts with ` ``` - [ ] **Step 3: Verify no stale references remain** ```bash grep -r "wait-for-feedback\|sendToClaude\|feedback-footer\|send-to-claude\|TaskOutput.*block.*true" /Users/drewritter/prime-rad/superpowers/ --include="*.js" --include="*.md" --include="*.sh" --include="*.html" | grep -v node_modules | grep -v RELEASE-NOTES | grep -v "\.md:.*spec\|plan" ``` Expected: No hits outside of release notes and the spec/plan docs (which are historical). - [ ] **Step 4: Final commit if any cleanup needed** ```bash git status # Review untracked/modified files, stage specific files as needed, commit if clean ``` ================================================ FILE: docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md ================================================ # Zero-Dependency Brainstorm Server Implementation Plan > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the brainstorm server's vendored node_modules with a single zero-dependency `server.js` using Node built-ins. **Architecture:** Single file with WebSocket protocol (RFC 6455 text frames), HTTP server (`http` module), and file watching (`fs.watch`). Exports protocol functions for unit testing when required as a module. **Tech Stack:** Node.js built-ins only: `http`, `crypto`, `fs`, `path` **Spec:** `docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md` **Existing tests:** `tests/brainstorm-server/ws-protocol.test.js` (unit), `tests/brainstorm-server/server.test.js` (integration) --- ## File Map - **Create:** `skills/brainstorming/scripts/server.js` — the zero-dep replacement - **Modify:** `skills/brainstorming/scripts/start-server.sh:94,100` — change `index.js` to `server.js` - **Modify:** `.gitignore:6` — remove the `!skills/brainstorming/scripts/node_modules/` exception - **Delete:** `skills/brainstorming/scripts/index.js` - **Delete:** `skills/brainstorming/scripts/package.json` - **Delete:** `skills/brainstorming/scripts/package-lock.json` - **Delete:** `skills/brainstorming/scripts/node_modules/` (714 files) - **No changes:** `skills/brainstorming/scripts/helper.js`, `skills/brainstorming/scripts/frame-template.html`, `skills/brainstorming/scripts/stop-server.sh` --- ## Chunk 1: WebSocket Protocol Layer ### Task 1: Implement WebSocket protocol exports **Files:** - Create: `skills/brainstorming/scripts/server.js` - Test: `tests/brainstorm-server/ws-protocol.test.js` (already exists) - [ ] **Step 1: Create server.js with OPCODES constant and computeAcceptKey** ```js const crypto = require('crypto'); const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A }; const WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; function computeAcceptKey(clientKey) { return crypto.createHash('sha1').update(clientKey + WS_MAGIC).digest('base64'); } ``` - [ ] **Step 2: Implement encodeFrame** Server frames are never masked. Three length encodings: - payload < 126: 2-byte header (FIN+opcode, length) - 126-65535: 4-byte header (FIN+opcode, 126, 16-bit length) - > 65535: 10-byte header (FIN+opcode, 127, 64-bit length) ```js function encodeFrame(opcode, payload) { const fin = 0x80; const len = payload.length; let header; if (len < 126) { header = Buffer.alloc(2); header[0] = fin | opcode; header[1] = len; } else if (len < 65536) { header = Buffer.alloc(4); header[0] = fin | opcode; header[1] = 126; header.writeUInt16BE(len, 2); } else { header = Buffer.alloc(10); header[0] = fin | opcode; header[1] = 127; header.writeBigUInt64BE(BigInt(len), 2); } return Buffer.concat([header, payload]); } ``` - [ ] **Step 3: Implement decodeFrame** Client frames are always masked. Returns `{ opcode, payload, bytesConsumed }` or `null` for incomplete. Throws on unmasked frames. ```js function decodeFrame(buffer) { if (buffer.length < 2) return null; const firstByte = buffer[0]; const secondByte = buffer[1]; const opcode = firstByte & 0x0F; const masked = (secondByte & 0x80) !== 0; let payloadLen = secondByte & 0x7F; let offset = 2; if (!masked) throw new Error('Client frames must be masked'); if (payloadLen === 126) { if (buffer.length < 4) return null; payloadLen = buffer.readUInt16BE(2); offset = 4; } else if (payloadLen === 127) { if (buffer.length < 10) return null; payloadLen = Number(buffer.readBigUInt64BE(2)); offset = 10; } const maskOffset = offset; const dataOffset = offset + 4; const totalLen = dataOffset + payloadLen; if (buffer.length < totalLen) return null; const mask = buffer.slice(maskOffset, dataOffset); const data = Buffer.alloc(payloadLen); for (let i = 0; i < payloadLen; i++) { data[i] = buffer[dataOffset + i] ^ mask[i % 4]; } return { opcode, payload: data, bytesConsumed: totalLen }; } ``` - [ ] **Step 4: Add module exports at the bottom of the file** ```js module.exports = { computeAcceptKey, encodeFrame, decodeFrame, OPCODES }; ``` - [ ] **Step 5: Run unit tests** Run: `cd tests/brainstorm-server && node ws-protocol.test.js` Expected: All tests pass (handshake, encoding, decoding, boundaries, edge cases) - [ ] **Step 6: Commit** ```bash git add skills/brainstorming/scripts/server.js git commit -m "Add WebSocket protocol layer for zero-dep brainstorm server" ``` --- ## Chunk 2: HTTP Server and Application Logic ### Task 2: Add HTTP server, file watching, and WebSocket connection handling **Files:** - Modify: `skills/brainstorming/scripts/server.js` - Test: `tests/brainstorm-server/server.test.js` (already exists) - [ ] **Step 1: Add configuration and constants at top of server.js (after requires)** ```js const http = require('http'); const fs = require('fs'); const path = require('path'); const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() * 16383)); const HOST = process.env.BRAINSTORM_HOST || '127.0.0.1'; const URL_HOST = process.env.BRAINSTORM_URL_HOST || (HOST === '127.0.0.1' ? 'localhost' : HOST); const SCREEN_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm'; const MIME_TYPES = { '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml' }; ``` - [ ] **Step 2: Add WAITING_PAGE, template loading at module scope, and helper functions** Load `frameTemplate` and `helperInjection` at module scope so they're accessible to `wrapInFrame` and `handleRequest`. They only read files from `__dirname` (the scripts directory), which is valid whether the module is required or run directly. ```js const WAITING_PAGE = ` Brainstorm Companion

Brainstorm Companion

Waiting for Claude to push a screen...

`; const frameTemplate = fs.readFileSync(path.join(__dirname, 'frame-template.html'), 'utf-8'); const helperScript = fs.readFileSync(path.join(__dirname, 'helper.js'), 'utf-8'); const helperInjection = ''; function isFullDocument(html) { const trimmed = html.trimStart().toLowerCase(); return trimmed.startsWith('', content); } function getNewestScreen() { const files = fs.readdirSync(SCREEN_DIR) .filter(f => f.endsWith('.html')) .map(f => { const fp = path.join(SCREEN_DIR, f); return { path: fp, mtime: fs.statSync(fp).mtime.getTime() }; }) .sort((a, b) => b.mtime - a.mtime); return files.length > 0 ? files[0].path : null; } ``` - [ ] **Step 3: Add HTTP request handler** ```js function handleRequest(req, res) { if (req.method === 'GET' && req.url === '/') { const screenFile = getNewestScreen(); let html = screenFile ? (raw => isFullDocument(raw) ? raw : wrapInFrame(raw))(fs.readFileSync(screenFile, 'utf-8')) : WAITING_PAGE; if (html.includes('')) { html = html.replace('', helperInjection + '\n'); } else { html += helperInjection; } res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(html); } else if (req.method === 'GET' && req.url.startsWith('/files/')) { const fileName = req.url.slice(7); // strip '/files/' const filePath = path.join(SCREEN_DIR, path.basename(fileName)); if (!fs.existsSync(filePath)) { res.writeHead(404); res.end('Not found'); return; } const ext = path.extname(filePath).toLowerCase(); const contentType = MIME_TYPES[ext] || 'application/octet-stream'; res.writeHead(200, { 'Content-Type': contentType }); res.end(fs.readFileSync(filePath)); } else { res.writeHead(404); res.end('Not found'); } } ``` - [ ] **Step 4: Add WebSocket connection handling** ```js const clients = new Set(); function handleUpgrade(req, socket) { const key = req.headers['sec-websocket-key']; if (!key) { socket.destroy(); return; } const accept = computeAcceptKey(key); socket.write( 'HTTP/1.1 101 Switching Protocols\r\n' + 'Upgrade: websocket\r\n' + 'Connection: Upgrade\r\n' + 'Sec-WebSocket-Accept: ' + accept + '\r\n\r\n' ); let buffer = Buffer.alloc(0); clients.add(socket); socket.on('data', (chunk) => { buffer = Buffer.concat([buffer, chunk]); while (buffer.length > 0) { let result; try { result = decodeFrame(buffer); } catch (e) { socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0))); clients.delete(socket); return; } if (!result) break; buffer = buffer.slice(result.bytesConsumed); switch (result.opcode) { case OPCODES.TEXT: handleMessage(result.payload.toString()); break; case OPCODES.CLOSE: socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0))); clients.delete(socket); return; case OPCODES.PING: socket.write(encodeFrame(OPCODES.PONG, result.payload)); break; case OPCODES.PONG: break; default: // Unsupported opcode — close with 1003 const closeBuf = Buffer.alloc(2); closeBuf.writeUInt16BE(1003); socket.end(encodeFrame(OPCODES.CLOSE, closeBuf)); clients.delete(socket); return; } } }); socket.on('close', () => clients.delete(socket)); socket.on('error', () => clients.delete(socket)); } function handleMessage(text) { let event; try { event = JSON.parse(text); } catch (e) { console.error('Failed to parse WebSocket message:', e.message); return; } console.log(JSON.stringify({ source: 'user-event', ...event })); if (event.choice) { const eventsFile = path.join(SCREEN_DIR, '.events'); fs.appendFileSync(eventsFile, JSON.stringify(event) + '\n'); } } function broadcast(msg) { const frame = encodeFrame(OPCODES.TEXT, Buffer.from(JSON.stringify(msg))); for (const socket of clients) { try { socket.write(frame); } catch (e) { clients.delete(socket); } } } ``` - [ ] **Step 5: Add debounce timer map** ```js const debounceTimers = new Map(); ``` File watching logic is inlined in `startServer` (Step 6) to keep watcher lifecycle together with server lifecycle and include an `error` handler per spec. - [ ] **Step 6: Add startServer function and conditional main** `frameTemplate` and `helperInjection` are already at module scope (Step 2). `startServer` just creates the screen dir, starts the HTTP server, watcher, and logs startup info. ```js function startServer() { if (!fs.existsSync(SCREEN_DIR)) fs.mkdirSync(SCREEN_DIR, { recursive: true }); const server = http.createServer(handleRequest); server.on('upgrade', handleUpgrade); const watcher = fs.watch(SCREEN_DIR, (eventType, filename) => { if (!filename || !filename.endsWith('.html')) return; if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename)); debounceTimers.set(filename, setTimeout(() => { debounceTimers.delete(filename); const filePath = path.join(SCREEN_DIR, filename); if (eventType === 'rename' && fs.existsSync(filePath)) { const eventsFile = path.join(SCREEN_DIR, '.events'); if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile); console.log(JSON.stringify({ type: 'screen-added', file: filePath })); } else if (eventType === 'change') { console.log(JSON.stringify({ type: 'screen-updated', file: filePath })); } broadcast({ type: 'reload' }); }, 100)); }); watcher.on('error', (err) => console.error('fs.watch error:', err.message)); server.listen(PORT, HOST, () => { const info = JSON.stringify({ type: 'server-started', port: Number(PORT), host: HOST, url_host: URL_HOST, url: 'http://' + URL_HOST + ':' + PORT, screen_dir: SCREEN_DIR }); console.log(info); fs.writeFileSync(path.join(SCREEN_DIR, '.server-info'), info + '\n'); }); } if (require.main === module) { startServer(); } ``` - [ ] **Step 7: Run integration tests** The test directory already has a `package.json` with `ws` as a dependency. Install it if needed, then run tests. Run: `cd tests/brainstorm-server && npm install && node server.test.js` Expected: All tests pass - [ ] **Step 8: Commit** ```bash git add skills/brainstorming/scripts/server.js git commit -m "Add HTTP server, WebSocket handling, and file watching to server.js" ``` --- ## Chunk 3: Swap and Cleanup ### Task 3: Update start-server.sh and remove old files **Files:** - Modify: `skills/brainstorming/scripts/start-server.sh:94,100` - Modify: `.gitignore:6` - Delete: `skills/brainstorming/scripts/index.js` - Delete: `skills/brainstorming/scripts/package.json` - Delete: `skills/brainstorming/scripts/package-lock.json` - Delete: `skills/brainstorming/scripts/node_modules/` (entire directory) - [ ] **Step 1: Update start-server.sh — change `index.js` to `server.js`** Two lines to change: Line 94: `env BRAINSTORM_DIR="$SCREEN_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" node server.js` Line 100: `nohup env BRAINSTORM_DIR="$SCREEN_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" node server.js > "$LOG_FILE" 2>&1 &` - [ ] **Step 2: Remove the gitignore exception for node_modules** In `.gitignore`, delete line 6: `!skills/brainstorming/scripts/node_modules/` - [ ] **Step 3: Delete old files** ```bash git rm skills/brainstorming/scripts/index.js git rm skills/brainstorming/scripts/package.json git rm skills/brainstorming/scripts/package-lock.json git rm -r skills/brainstorming/scripts/node_modules/ ``` - [ ] **Step 4: Run both test suites** Run: `cd tests/brainstorm-server && node ws-protocol.test.js && node server.test.js` Expected: All tests pass - [ ] **Step 5: Commit** ```bash git add skills/brainstorming/scripts/ .gitignore git commit -m "Remove vendored node_modules, swap to zero-dep server.js" ``` ### Task 4: Manual smoke test - [ ] **Step 1: Start the server manually** ```bash cd skills/brainstorming/scripts BRAINSTORM_DIR=/tmp/brainstorm-smoke BRAINSTORM_PORT=9876 node server.js ``` Expected: `server-started` JSON printed with port 9876 - [ ] **Step 2: Open browser to http://localhost:9876** Expected: Waiting page with "Waiting for Claude to push a screen..." - [ ] **Step 3: Write an HTML file to the screen directory** ```bash echo '

Hello from smoke test

' > /tmp/brainstorm-smoke/test.html ``` Expected: Browser reloads and shows "Hello from smoke test" wrapped in frame template - [ ] **Step 4: Verify WebSocket works — check browser console** Open browser dev tools. The WebSocket connection should show as connected (no errors in console). The frame template's status indicator should show "Connected". - [ ] **Step 5: Stop server with Ctrl-C, clean up** ```bash rm -rf /tmp/brainstorm-smoke ``` ================================================ FILE: docs/superpowers/specs/2026-01-22-document-review-system-design.md ================================================ # Document Review System Design ## Overview Add two new review stages to the superpowers workflow: 1. **Spec Document Review** - After brainstorming, before writing-plans 2. **Plan Document Review** - After writing-plans, before implementation Both follow the iterative loop pattern used by implementation reviews. ## Spec Document Reviewer **Purpose:** Verify the spec is complete, consistent, and ready for implementation planning. **Location:** `skills/brainstorming/spec-document-reviewer-prompt.md` **What it checks for:** | Category | What to Look For | |----------|------------------| | Completeness | TODOs, placeholders, "TBD", incomplete sections | | Coverage | Missing error handling, edge cases, integration points | | Consistency | Internal contradictions, conflicting requirements | | Clarity | Ambiguous requirements | | YAGNI | Unrequested features, over-engineering | **Output format:** ``` ## Spec Review **Status:** Approved | Issues Found **Issues (if any):** - [Section X]: [issue] - [why it matters] **Recommendations (advisory):** - [suggestions that don't block approval] ``` **Review loop:** Issues found -> brainstorming agent fixes -> re-review -> repeat until approved. **Dispatch mechanism:** Use the Task tool with `subagent_type: general-purpose`. The reviewer prompt template provides the full prompt. The brainstorming skill's controller dispatches the reviewer. ## Plan Document Reviewer **Purpose:** Verify the plan is complete, matches the spec, and has proper task decomposition. **Location:** `skills/writing-plans/plan-document-reviewer-prompt.md` **What it checks for:** | Category | What to Look For | |----------|------------------| | Completeness | TODOs, placeholders, incomplete tasks | | Spec Alignment | Plan covers spec requirements, no scope creep | | Task Decomposition | Tasks atomic, clear boundaries | | Task Syntax | Checkbox syntax on tasks and steps | | Chunk Size | Each chunk under 1000 lines | **Chunk definition:** A chunk is a logical grouping of tasks within the plan document, delimited by `## Chunk N: ` headings. The writing-plans skill creates these boundaries based on logical phases (e.g., "Foundation", "Core Features", "Integration"). Each chunk should be self-contained enough to review independently. **Spec alignment verification:** The reviewer receives both: 1. The plan document (or current chunk) 2. The path to the spec document for reference The reviewer reads both and compares requirements coverage. **Output format:** Same as spec reviewer, but scoped to the current chunk. **Review process (chunk-by-chunk):** 1. Writing-plans creates chunk N 2. Controller dispatches plan-document-reviewer with chunk N content and spec path 3. Reviewer reads chunk and spec, returns verdict 4. If issues: writing-plans agent fixes chunk N, goto step 2 5. If approved: proceed to chunk N+1 6. Repeat until all chunks approved **Dispatch mechanism:** Same as spec reviewer - Task tool with `subagent_type: general-purpose`. ## Updated Workflow ``` brainstorming -> spec -> SPEC REVIEW LOOP -> writing-plans -> plan -> PLAN REVIEW LOOP -> implementation ``` **Spec Review Loop:** 1. Spec complete 2. Dispatch reviewer 3. If issues: fix -> goto 2 4. If approved: proceed **Plan Review Loop:** 1. Chunk N complete 2. Dispatch reviewer for chunk N 3. If issues: fix -> goto 2 4. If approved: next chunk or implementation ## Markdown Task Syntax Tasks and steps use checkbox syntax: ```markdown - [ ] ### Task 1: Name - [ ] **Step 1:** Description - File: path - Command: cmd ``` ## Error Handling **Review loop termination:** - No hard iteration limit - loops continue until reviewer approves - If loop exceeds 5 iterations, the controller should surface this to the human for guidance - The human can choose to: continue iterating, approve with known issues, or abort **Disagreement handling:** - Reviewers are advisory - they flag issues but don't block - If the agent believes reviewer feedback is incorrect, it should explain why in its fix - If disagreement persists after 3 iterations on the same issue, surface to human **Malformed reviewer output:** - Controller should validate reviewer output has required fields (Status, Issues if applicable) - If malformed, re-dispatch reviewer with a note about expected format - After 2 malformed responses, surface to human ## Files to Change **New files:** - `skills/brainstorming/spec-document-reviewer-prompt.md` - `skills/writing-plans/plan-document-reviewer-prompt.md` **Modified files:** - `skills/brainstorming/SKILL.md` - add review loop after spec written - `skills/writing-plans/SKILL.md` - add chunk-by-chunk review loop, update task syntax examples ================================================ FILE: docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md ================================================ # Visual Brainstorming Refactor: Browser Displays, Terminal Commands **Date:** 2026-02-19 **Status:** Approved **Scope:** `lib/brainstorm-server/`, `skills/brainstorming/visual-companion.md`, `tests/brainstorm-server/` ## Problem During visual brainstorming, Claude runs `wait-for-feedback.sh` as a background task and blocks on `TaskOutput(block=true, timeout=600s)`. This seizes the TUI entirely — the user cannot type to Claude while visual brainstorming is running. The browser becomes the only input channel. Claude Code's execution model is turn-based. There is no way for Claude to listen on two channels simultaneously within a single turn. The blocking `TaskOutput` pattern was the wrong primitive — it simulates event-driven behavior the platform doesn't support. ## Design ### Core Model **Browser = interactive display.** Shows mockups, lets the user click to select options. Selections are recorded server-side. **Terminal = conversation channel.** Always unblocked, always available. The user talks to Claude here. ### The Loop 1. Claude writes an HTML file to the session directory 2. Server detects it via chokidar, pushes WebSocket reload to the browser (unchanged) 3. Claude ends its turn — tells the user to check the browser and respond in the terminal 4. User looks at browser, optionally clicks to select an option, then types feedback in the terminal 5. On the next turn, Claude reads `$SCREEN_DIR/.events` for the browser interaction stream (clicks, selections), merges with the terminal text 6. Iterate or advance No background tasks. No `TaskOutput` blocking. No polling scripts. ### Key Deletion: `wait-for-feedback.sh` Deleted entirely. Its purpose was to bridge "server logs events to stdout" and "Claude needs to receive those events." The `.events` file replaces this — the server writes user interaction events directly, and Claude reads them with whatever file-reading mechanism the platform provides. ### Key Addition: `.events` File (Per-Screen Event Stream) The server writes all user interaction events to `$SCREEN_DIR/.events`, one JSON object per line. This gives Claude the full interaction stream for the current screen — not just the final selection, but the user's exploration path (clicked A, then B, settled on C). Example contents after a user explores options: ```jsonl {"type":"click","choice":"a","text":"Option A - Preset-First Wizard","timestamp":1706000101} {"type":"click","choice":"c","text":"Option C - Manual Config","timestamp":1706000108} {"type":"click","choice":"b","text":"Option B - Hybrid Approach","timestamp":1706000115} ``` - Append-only within a screen. Each user event is appended as a new line. - The file is cleared (deleted) when chokidar detects a new HTML file (new screen pushed), preventing stale events from carrying over. - If the file doesn't exist when Claude reads it, no browser interaction occurred — Claude uses only the terminal text. - The file contains only user events (`click`, etc.) — not server lifecycle events (`server-started`, `screen-added`). This keeps it small and focused. - Claude can read the full stream to understand the user's exploration pattern, or just look at the last `choice` event for the final selection. ## Changes by File ### `index.js` (server) **A. Write user events to `.events` file.** In the WebSocket `message` handler, after logging the event to stdout: append the event as a JSON line to `$SCREEN_DIR/.events` via `fs.appendFileSync`. Only write user interaction events (those with `source: 'user-event'`), not server lifecycle events. **B. Clear `.events` on new screen.** In the chokidar `add` handler (new `.html` file detected), delete `$SCREEN_DIR/.events` if it exists. This is the definitive "new screen" signal — better than clearing on GET `/` which fires on every reload. **C. Replace `wrapInFrame` content injection.** The current regex anchors on `