Compare commits

...

38 Commits

Author SHA1 Message Date
Drew Ritter
2b2a7efa7d Fix stale Codex skills path in writing-skills SKILL.md
~/.codex/skills/ is deprecated; Codex uses ~/.agents/skills/ via native discovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:09:57 -08:00
Drew Ritter
ac65720a98 Add Windows uninstall instructions and expand migration steps
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:03:19 -08:00
Drew Ritter
f4db4a7ab0 Drop installer script and AGENTS.md gatekeeper
Testing showed native skill discovery works without the AGENTS.md
gatekeeper — using-superpowers bootstraps itself via SKILL.md
frontmatter. Install is now just clone + symlink, driven by
INSTALL.md. No Node.js dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:53:22 -08:00
Drew Ritter
70d85021b0 Fix path resolution and symlink removal in Codex installer
Use fileURLToPath() instead of manual URL pathname parsing to correctly
handle paths with spaces and special characters on all platforms.
Replace execSync rm/rmdir with fs.unlinkSync for stale symlink removal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:37:31 -08:00
Drew Ritter
9ee2552fe5 Polish docs from 5-agent review
- INSTALL.md: add prerequisites, Windows note, verify step, clone
  deletion in uninstall
- README.codex.md: fix Windows section (junctions not symlinks),
  add description field guidance, consistent terminology
- install-codex.mjs: accurate link type labels (symlink vs junction)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:34:05 -08:00
Drew Ritter
f2e3cb7650 Rewrite Codex docs for native skill discovery
Replaces bootstrap CLI references with native discovery flow.
Install is now clone + run installer. Documents tool mappings,
personal skills path, and Windows junction fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:03:38 -08:00
Drew Ritter
9a6f4da203 Rewrite INSTALL.md for native skill discovery
Two-step install: clone + run installer. Replaces the old manual
setup that required editing AGENTS.md by hand.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:03:10 -08:00
Drew Ritter
654106c4ac Add minimal Codex installer for native skill discovery
Creates symlink from ~/.agents/skills/superpowers to repo skills dir,
updates ~/.codex/AGENTS.md with gatekeeper block, removes old bootstrap
block if present. Windows junction fallback when symlinks are blocked.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:02:54 -08:00
Drew Ritter
e0effac27c Remove bootstrap CLI and related files
The bootstrap CLI (superpowers-codex), Windows wrapper, and bootstrap
content file are no longer needed — Codex now has native skill discovery
that replaces this mechanism.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:00:46 -08:00
Drew Ritter
ac6d7b878b Migrate Codex integration from bootstrap CLI to native skill discovery 2026-02-05 16:00:05 -08:00
Drew Ritter
1143f9be3d Fix ~/ path expansion on Windows — use $HOME instead
PowerShell doesn't expand ~ when passed as an argument to node,
causing MODULE_NOT_FOUND errors. $HOME expands correctly in both
bash and PowerShell.

Fixes #285

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 12:11:11 -08:00
Drew Ritter
6cc2d8c920 Fix Windows/PowerShell invocation of superpowers-codex
Windows doesn't respect shebangs, so directly invoking the extensionless
superpowers-codex script triggers an "Open with" dialog. Prefix all
invocations with `node` (harmless on Unix, required on Windows) and add
a .cmd wrapper for manual invocation on Windows.

Fixes #285, #243

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 11:54:57 -08:00
Jesse Vincent
038abed026 fix: replace O(n^2) escape_for_json with parameter substitution
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, freezing terminal input even with async hooks.

Replaced with bash parameter substitution (${s//old/new}) which runs
each pattern as a single C-level pass. 7x faster on macOS, expected
to be dramatically faster on Windows Git Bash where the original
caused the worst hangs.

Relates to #404, #413
2026-02-05 11:38:06 -08:00
Jesse Vincent
961052e0f9 fix: run SessionStart hook async to prevent Windows terminal freeze
The synchronous SessionStart hook blocked the TUI from entering raw
mode on Windows, freezing all keyboard input. The pure-bash
escape_for_json function is O(n^2) on Git Bash, taking 60+ seconds.

Running the hook async prevents the freeze while still injecting
superpowers context. Multiple users confirmed this workaround.

Fixes #404, #413, #414, #419
2026-02-05 11:33:58 -08:00
Jesse Vincent
689e2a77fc fix: Windows hook execution for Claude Code 2.1.x (#331)
* fix: convert shell scripts from CRLF to LF line endings

Add .gitattributes to enforce LF line endings for shell scripts,
preventing bash errors like "/usr/bin/bash: line 1: : command not found"
when scripts are checked out on Windows with CRLF.

Fixes #317 (SessionStart hook fails due to CRLF line endings)

Files converted:
- hooks/session-start.sh
- lib/brainstorm-server/start-server.sh
- lib/brainstorm-server/stop-server.sh
- lib/brainstorm-server/wait-for-feedback.sh
- skills/systematic-debugging/find-polluter.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update Windows hook execution for Claude Code 2.1.x

Claude Code 2.1.x changed the Windows execution model: it now auto-detects
.sh files in hook commands and prepends "bash " automatically. This broke
the polyglot wrapper because:

  Before: "run-hook.cmd" session-start.sh  (wrapper executes)
  After:  bash "run-hook.cmd" session-start.sh  (bash can't run .cmd)

Changes:
- hooks.json now calls session-start.sh directly (Claude Code handles bash)
- Added deprecation comment to run-hook.cmd explaining the change
- Updated RELEASE-NOTES.md

Fixes #317, #313, #275, #292

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 11:33:25 -08:00
Jesse Vincent
5e0d2f8175 Simplify installation verification instructions
Remove /help command check and specific slash command list. Skills are
primarily invoked by describing what you want to do, not by running
specific commands.
2026-02-05 11:32:46 -08:00
Jesse Vincent
06b92f3682 Merge pull request #382 from clkao/fix/subagent-worktree-requirement
fix: require worktree setup before subagent-driven-development and executing-plans
2026-01-30 09:51:30 -08:00
Jesse Vincent
9819209bba Merge pull request #361 from deinspanjer/codex-bootstrap-support-collab-subagent
Codex: clarify subagent tool mapping in bootstrap + README
2026-01-30 09:48:29 -08:00
CL Kao
c7816ee2a6 docs: change main branch red flag to require explicit user consent
Instead of prohibiting main branch work entirely, allow it with explicit
user consent. This is more flexible while still ensuring users are aware
of the implications.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 15:12:50 -08:00
CL Kao
b323e35805 docs(executing-plans): add worktree requirement before executing plans
Add Integration section referencing using-git-worktrees skill as required,
consistent with subagent-driven-development skill. Also add reminder to
never start on main/master branch.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:48:24 -08:00
CL Kao
bb2ff5d309 docs(using-git-worktrees): add subagent/executing-plans as callers
Update Integration section to show bidirectional relationship:
subagent-driven-development and executing-plans now list
using-git-worktrees as required, so this skill should list
them as callers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:46:45 -08:00
CL Kao
b63d485955 docs(subagent-driven-development): add main branch red flag to Never list
Add explicit warning against starting implementation on main/master
branch without first using a worktree for isolation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:45:04 -08:00
CL Kao
fa3f46d4e9 docs(subagent-driven-development): add using-git-worktrees as required skill
Adds using-git-worktrees as the first required workflow skill in the
Integration section. This makes explicit that an isolated workspace
should be set up before starting subagent-driven development.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:43:33 -08:00
CL Kao
f8dbe7b196 test: add Test 9 - main branch red flag warning
TDD: Test verifies that subagent-driven-development skill warns
against starting implementation directly on main/master branch.
Test expects skill to recommend worktree or feature branch instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:41:39 -08:00
CL Kao
93cf2ee84f test: add worktree requirement test for subagent-driven-development
Add Test 8 to verify that using-git-worktrees is mentioned as a required
skill for subagent-driven-development. This test will initially fail per
TDD approach - the skill file needs to be updated to pass this test.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:39:50 -08:00
CL Kao
1872f50b64 fix(tests): handle case variations in skill recognition test
The assertion now matches "subagent-driven-development", "Subagent-Driven
Development", and "Subagent Driven" since Claude's responses may use
different casing and formatting styles.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:34:38 -08:00
Daniel E.
8904b7d9dc codex: clarify subagent tool mapping in bootstrap 2026-01-25 18:42:22 -05:00
Jesse Vincent
469a6d81eb Merge pull request #349 from obra/fix/opencode-issues
fix(opencode): standardize on plugins/ directory, fix symlink docs
2026-01-23 12:09:13 -08:00
Jesse Vincent
4b6cef98ac chore: bump version to 4.1.1
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:08:47 +00:00
Jesse Vincent
03087b13b8 fix(opencode): standardize on plugins/ directory per official docs
OpenCode officially documents ~/.config/opencode/plugins/ (plural) as the
plugin directory. Our docs previously used plugin/ (singular), which also
works but caused confusion.

Changes:
- Renamed .opencode/plugin/ to .opencode/plugins/ in repo structure
- Updated INSTALL.md to use plugins/ everywhere
- Updated README.opencode.md (all platforms: Linux, macOS, Windows CMD,
  PowerShell, Git Bash) to use plugins/
- Updated test scripts to match

Tested: Both singular and plural forms work, but we now match official docs.

Fixes #343

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:31:45 +00:00
Jesse Vincent
493ac18dfe fix(opencode): update docs for native skills, fix symlink instructions
Issues addressed:
- #342: INSTALL.md still referenced removed find_skills/use_skill tools
- #339: Symlink instructions could fail if target already exists

Changes:
- INSTALL.md: Added missing skills symlink step, updated to native skill tool
- INSTALL.md: Removed Node.js prerequisite (no longer needed)
- README.opencode.md: Added explicit rm before ln -s (ln -sf doesn't remove dirs)
- Both files: Use ln -s instead of ln -sf for clarity

Note: #343 (plugin vs plugins folder name) not addressed in this commit

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 17:33:23 +00:00
Jesse Vincent
35d4fbcd0b chore: bump plugin version to 4.1.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 04:10:23 +00:00
Jesse Vincent
19c70afc99 chore: release v4.1.0
Breaking changes:
- OpenCode: Switched to native skills system (migration required)

Fixes:
- OpenCode: Fixed agent reset on session start (#226)
- OpenCode: Fixed Windows installation (#232)
- Claude Code: Fixed Windows hook execution for 2.1.x

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 04:07:35 +00:00
Jesse Vincent
405a025eea Merge pull request #335 from obra/fixes-for-main
fix: OpenCode native skills + Windows hook execution
2026-01-22 20:06:45 -08:00
Jesse Vincent
36fcd57626 fix: Windows hook execution for Claude Code 2.1.x (#331)
* fix: convert shell scripts from CRLF to LF line endings

Add .gitattributes to enforce LF line endings for shell scripts,
preventing bash errors like "/usr/bin/bash: line 1: : command not found"
when scripts are checked out on Windows with CRLF.

Fixes #317 (SessionStart hook fails due to CRLF line endings)

Files converted:
- hooks/session-start.sh
- lib/brainstorm-server/start-server.sh
- lib/brainstorm-server/stop-server.sh
- lib/brainstorm-server/wait-for-feedback.sh
- skills/systematic-debugging/find-polluter.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update Windows hook execution for Claude Code 2.1.x

Claude Code 2.1.x changed the Windows execution model: it now auto-detects
.sh files in hook commands and prepends "bash " automatically. This broke
the polyglot wrapper because:

  Before: "run-hook.cmd" session-start.sh  (wrapper executes)
  After:  bash "run-hook.cmd" session-start.sh  (bash can't run .cmd)

Changes:
- hooks.json now calls session-start.sh directly (Claude Code handles bash)
- Added deprecation comment to run-hook.cmd explaining the change
- Updated RELEASE-NOTES.md

Fixes #317, #313, #275, #292

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 03:56:52 +00:00
Jesse Vincent
3964d18670 feat(opencode): use native skills and fix agent reset bug (#226) (#330)
* fix use_skill agent context (#290)

* fix: respect OPENCODE_CONFIG_DIR for personal skills lookup (#297)

* fix: respect OPENCODE_CONFIG_DIR for personal skills lookup

The plugin was hardcoded to look for personal skills in ~/.config/opencode/skills,
ignoring users who set OPENCODE_CONFIG_DIR to a custom path (e.g., for dotfiles management).

Now uses OPENCODE_CONFIG_DIR if set, falling back to the default path.

* fix: update help text to use dynamic paths

Use configDir and personalSkillsDir variables in help text so paths
are accurate when OPENCODE_CONFIG_DIR is set.

* fix: normalize OPENCODE_CONFIG_DIR before use

Handle edge cases where the env var might be:
- Empty or whitespace-only
- Using ~ for home directory (common in .env files)
- A relative path

Now trims, expands ~, and resolves to absolute path.

* feat(opencode): use native skills and fix agent reset bug (#226)

- Replace custom use_skill/find_skills tools with OpenCode's native skill tool
- Use experimental.chat.system.transform hook instead of session.prompt
  (fixes #226 agent reset on first message)
- Symlink skills directory into ~/.config/opencode/skills/superpowers/
- Update installation docs with comprehensive Windows support:
  - Command Prompt, PowerShell, and Git Bash instructions
  - Proper symlink vs junction handling
  - Reinstall safety with cleanup steps
  - Verification commands for each shell

* Add OpenCode native skills changes to release notes

Documents:
- Breaking change: switch to native skill tool
- Fix for agent reset bug (#226)
- Fix for Windows installation (#232)

---------

Co-authored-by: Vinicius da Motta <viniciusmotta8@gmail.com>
Co-authored-by: oribi <oribarilan@gmail.com>
2026-01-23 03:56:12 +00:00
oribi
a01a135fe1 fix: respect OPENCODE_CONFIG_DIR for personal skills lookup (#297)
* fix: respect OPENCODE_CONFIG_DIR for personal skills lookup

The plugin was hardcoded to look for personal skills in ~/.config/opencode/skills,
ignoring users who set OPENCODE_CONFIG_DIR to a custom path (e.g., for dotfiles management).

Now uses OPENCODE_CONFIG_DIR if set, falling back to the default path.

* fix: update help text to use dynamic paths

Use configDir and personalSkillsDir variables in help text so paths
are accurate when OPENCODE_CONFIG_DIR is set.

* fix: normalize OPENCODE_CONFIG_DIR before use

Handle edge cases where the env var might be:
- Empty or whitespace-only
- Using ~ for home directory (common in .env files)
- A relative path

Now trims, expands ~, and resolves to absolute path.
2026-01-19 13:54:50 -08:00
Vinicius da Motta
ac471e69c2 fix use_skill agent context (#290) 2026-01-18 17:02:48 -08:00
22 changed files with 634 additions and 802 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "superpowers",
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
"version": "4.0.3",
"version": "4.1.1",
"author": {
"name": "Jesse Vincent",
"email": "jesse@fsck.com"

View File

@@ -1,35 +1,67 @@
# Installing Superpowers for Codex
Quick setup to enable superpowers skills in Codex.
Enable superpowers skills in Codex via native skill discovery. Just clone and symlink.
## Prerequisites
- Git
## Installation
1. **Clone superpowers repository**:
1. **Clone the superpowers repository:**
```bash
mkdir -p ~/.codex/superpowers
cd ~/.codex/superpowers
git clone https://github.com/obra/superpowers.git .
git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
```
2. **Create personal skills directory**:
2. **Create the skills symlink:**
```bash
mkdir -p ~/.codex/skills
mkdir -p ~/.agents/skills
ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers
```
3. **Update ~/.codex/AGENTS.md** to include this superpowers section:
```markdown
## Superpowers System
<EXTREMELY_IMPORTANT>
You have superpowers. Superpowers teach you new skills and capabilities. RIGHT NOW run: `~/.codex/superpowers/.codex/superpowers-codex bootstrap` and follow the instructions it returns.
</EXTREMELY_IMPORTANT>
**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"
```
## Verification
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
Test the installation:
```bash
~/.codex/superpowers/.codex/superpowers-codex bootstrap
ls -la ~/.agents/skills/superpowers
```
You should see skill listings and bootstrap instructions. The system is now ready for use.
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`.

View File

@@ -1,33 +0,0 @@
# Superpowers Bootstrap for Codex
<EXTREMELY_IMPORTANT>
You have superpowers.
**Tool for running skills:**
- `~/.codex/superpowers/.codex/superpowers-codex use-skill <skill-name>`
**Tool Mapping for Codex:**
When skills reference tools you don't have, substitute your equivalent tools:
- `TodoWrite``update_plan` (your planning/task tracking tool)
- `Task` tool with subagents → Tell the user that subagents aren't available in Codex yet and you'll do the work the subagent would do
- `Skill` tool → `~/.codex/superpowers/.codex/superpowers-codex use-skill` command (already available)
- `Read`, `Write`, `Edit`, `Bash` → Use your native tools with similar functions
**Skills naming:**
- Superpowers skills: `superpowers:skill-name` (from ~/.codex/superpowers/skills/)
- Personal skills: `skill-name` (from ~/.codex/skills/)
- Personal skills override superpowers skills when names match
**Critical Rules:**
- Before ANY task, review the skills list (shown below)
- If a relevant skill exists, you MUST use `~/.codex/superpowers/.codex/superpowers-codex use-skill` to load it
- Announce: "I've read the [Skill Name] skill and I'm using it to [purpose]"
- Skills with checklists require `update_plan` todos for each item
- NEVER skip mandatory workflows (brainstorming before coding, TDD, systematic debugging)
**Skills location:**
- Superpowers skills: ~/.codex/superpowers/skills/
- Personal skills: ~/.codex/skills/ (override superpowers when names match)
IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT.
</EXTREMELY_IMPORTANT>

View File

@@ -1,267 +0,0 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const os = require('os');
const skillsCore = require('../lib/skills-core');
// Paths
const homeDir = os.homedir();
const superpowersSkillsDir = path.join(homeDir, '.codex', 'superpowers', 'skills');
const personalSkillsDir = path.join(homeDir, '.codex', 'skills');
const bootstrapFile = path.join(homeDir, '.codex', 'superpowers', '.codex', 'superpowers-bootstrap.md');
const superpowersRepoDir = path.join(homeDir, '.codex', 'superpowers');
// Utility functions
function printSkill(skillPath, sourceType) {
const skillFile = path.join(skillPath, 'SKILL.md');
const relPath = sourceType === 'personal'
? path.relative(personalSkillsDir, skillPath)
: path.relative(superpowersSkillsDir, skillPath);
// Print skill name with namespace
if (sourceType === 'personal') {
console.log(relPath.replace(/\\/g, '/')); // Personal skills are not namespaced
} else {
console.log(`superpowers:${relPath.replace(/\\/g, '/')}`); // Superpowers skills get superpowers namespace
}
// Extract and print metadata
const { name, description } = skillsCore.extractFrontmatter(skillFile);
if (description) console.log(` ${description}`);
console.log('');
}
// Commands
function runFindSkills() {
console.log('Available skills:');
console.log('==================');
console.log('');
const foundSkills = new Set();
// Find personal skills first (these take precedence)
const personalSkills = skillsCore.findSkillsInDir(personalSkillsDir, 'personal', 2);
for (const skill of personalSkills) {
const relPath = path.relative(personalSkillsDir, skill.path);
foundSkills.add(relPath);
printSkill(skill.path, 'personal');
}
// Find superpowers skills (only if not already found in personal)
const superpowersSkills = skillsCore.findSkillsInDir(superpowersSkillsDir, 'superpowers', 1);
for (const skill of superpowersSkills) {
const relPath = path.relative(superpowersSkillsDir, skill.path);
if (!foundSkills.has(relPath)) {
printSkill(skill.path, 'superpowers');
}
}
console.log('Usage:');
console.log(' superpowers-codex use-skill <skill-name> # Load a specific skill');
console.log('');
console.log('Skill naming:');
console.log(' Superpowers skills: superpowers:skill-name (from ~/.codex/superpowers/skills/)');
console.log(' Personal skills: skill-name (from ~/.codex/skills/)');
console.log(' Personal skills override superpowers skills when names match.');
console.log('');
console.log('Note: All skills are disclosed at session start via bootstrap.');
}
function runBootstrap() {
console.log('# Superpowers Bootstrap for Codex');
console.log('# ================================');
console.log('');
// Check for updates (with timeout protection)
if (skillsCore.checkForUpdates(superpowersRepoDir)) {
console.log('## Update Available');
console.log('');
console.log('⚠️ Your superpowers installation is behind the latest version.');
console.log('To update, run: `cd ~/.codex/superpowers && git pull`');
console.log('');
console.log('---');
console.log('');
}
// Show the bootstrap instructions
if (fs.existsSync(bootstrapFile)) {
console.log('## Bootstrap Instructions:');
console.log('');
try {
const content = fs.readFileSync(bootstrapFile, 'utf8');
console.log(content);
} catch (error) {
console.log(`Error reading bootstrap file: ${error.message}`);
}
console.log('');
console.log('---');
console.log('');
}
// Run find-skills to show available skills
console.log('## Available Skills:');
console.log('');
runFindSkills();
console.log('');
console.log('---');
console.log('');
// Load the using-superpowers skill automatically
console.log('## Auto-loading superpowers:using-superpowers skill:');
console.log('');
runUseSkill('superpowers:using-superpowers');
console.log('');
console.log('---');
console.log('');
console.log('# Bootstrap Complete!');
console.log('# You now have access to all superpowers skills.');
console.log('# Use "superpowers-codex use-skill <skill>" to load and apply skills.');
console.log('# Remember: If a skill applies to your task, you MUST use it!');
}
function runUseSkill(skillName) {
if (!skillName) {
console.log('Usage: superpowers-codex use-skill <skill-name>');
console.log('Examples:');
console.log(' superpowers-codex use-skill superpowers:brainstorming # Load superpowers skill');
console.log(' superpowers-codex use-skill brainstorming # Load personal skill (or superpowers if not found)');
console.log(' superpowers-codex use-skill my-custom-skill # Load personal skill');
return;
}
// Handle namespaced skill names
let actualSkillPath;
let forceSuperpowers = false;
if (skillName.startsWith('superpowers:')) {
// Remove the superpowers: namespace prefix
actualSkillPath = skillName.substring('superpowers:'.length);
forceSuperpowers = true;
} else {
actualSkillPath = skillName;
}
// Remove "skills/" prefix if present
if (actualSkillPath.startsWith('skills/')) {
actualSkillPath = actualSkillPath.substring('skills/'.length);
}
// Function to find skill file
function findSkillFile(searchPath) {
// Check for exact match with SKILL.md
const skillMdPath = path.join(searchPath, 'SKILL.md');
if (fs.existsSync(skillMdPath)) {
return skillMdPath;
}
// Check for direct SKILL.md file
if (searchPath.endsWith('SKILL.md') && fs.existsSync(searchPath)) {
return searchPath;
}
return null;
}
let skillFile = null;
// If superpowers: namespace was used, only check superpowers skills
if (forceSuperpowers) {
if (fs.existsSync(superpowersSkillsDir)) {
const superpowersPath = path.join(superpowersSkillsDir, actualSkillPath);
skillFile = findSkillFile(superpowersPath);
}
} else {
// First check personal skills directory (takes precedence)
if (fs.existsSync(personalSkillsDir)) {
const personalPath = path.join(personalSkillsDir, actualSkillPath);
skillFile = findSkillFile(personalPath);
if (skillFile) {
console.log(`# Loading personal skill: ${actualSkillPath}`);
console.log(`# Source: ${skillFile}`);
console.log('');
}
}
// If not found in personal, check superpowers skills
if (!skillFile && fs.existsSync(superpowersSkillsDir)) {
const superpowersPath = path.join(superpowersSkillsDir, actualSkillPath);
skillFile = findSkillFile(superpowersPath);
if (skillFile) {
console.log(`# Loading superpowers skill: superpowers:${actualSkillPath}`);
console.log(`# Source: ${skillFile}`);
console.log('');
}
}
}
// If still not found, error
if (!skillFile) {
console.log(`Error: Skill not found: ${actualSkillPath}`);
console.log('');
console.log('Available skills:');
runFindSkills();
return;
}
// Extract frontmatter and content using shared core functions
let content, frontmatter;
try {
const fullContent = fs.readFileSync(skillFile, 'utf8');
const { name, description } = skillsCore.extractFrontmatter(skillFile);
content = skillsCore.stripFrontmatter(fullContent);
frontmatter = { name, description };
} catch (error) {
console.log(`Error reading skill file: ${error.message}`);
return;
}
// Display skill header with clean info
const displayName = forceSuperpowers ? `superpowers:${actualSkillPath}` :
(skillFile.includes(personalSkillsDir) ? actualSkillPath : `superpowers:${actualSkillPath}`);
const skillDirectory = path.dirname(skillFile);
console.log(`# ${frontmatter.name || displayName}`);
if (frontmatter.description) {
console.log(`# ${frontmatter.description}`);
}
console.log(`# Skill-specific tools and reference files live in ${skillDirectory}`);
console.log('# ============================================');
console.log('');
// Display the skill content (without frontmatter)
console.log(content);
}
// Main CLI
const command = process.argv[2];
const arg = process.argv[3];
switch (command) {
case 'bootstrap':
runBootstrap();
break;
case 'use-skill':
runUseSkill(arg);
break;
case 'find-skills':
runFindSkills();
break;
default:
console.log('Superpowers for Codex');
console.log('Usage:');
console.log(' superpowers-codex bootstrap # Run complete bootstrap with all skills');
console.log(' superpowers-codex use-skill <skill-name> # Load a specific skill');
console.log(' superpowers-codex find-skills # List all available skills');
console.log('');
console.log('Examples:');
console.log(' superpowers-codex bootstrap');
console.log(' superpowers-codex use-skill superpowers:brainstorming');
console.log(' superpowers-codex use-skill my-custom-skill');
break;
}

17
.gitattributes vendored Normal file
View File

@@ -0,0 +1,17 @@
# Ensure shell scripts always have LF line endings
*.sh 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

View File

@@ -3,15 +3,13 @@
## Prerequisites
- [OpenCode.ai](https://opencode.ai) installed
- Node.js installed
- Git installed
## Installation Steps
### 1. Install Superpowers
### 1. Clone Superpowers
```bash
mkdir -p ~/.config/opencode/superpowers
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
```
@@ -20,32 +18,43 @@ git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
Create a symlink so OpenCode discovers the plugin:
```bash
mkdir -p ~/.config/opencode/plugin
ln -sf ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js ~/.config/opencode/plugin/superpowers.js
mkdir -p ~/.config/opencode/plugins
rm -f ~/.config/opencode/plugins/superpowers.js
ln -s ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js ~/.config/opencode/plugins/superpowers.js
```
### 3. Restart OpenCode
### 3. Symlink Skills
Restart OpenCode. The plugin will automatically inject superpowers context via the chat.message hook.
Create a symlink so OpenCode's native skill tool discovers superpowers skills:
You should see superpowers is active when you ask "do you have superpowers?"
```bash
mkdir -p ~/.config/opencode/skills
rm -rf ~/.config/opencode/skills/superpowers
ln -s ~/.config/opencode/superpowers/skills ~/.config/opencode/skills/superpowers
```
### 4. Restart OpenCode
Restart OpenCode. The plugin will automatically inject superpowers context.
Verify by asking: "do you have superpowers?"
## Usage
### Finding Skills
Use the `find_skills` tool to list all available skills:
Use OpenCode's native `skill` tool to list available skills:
```
use find_skills tool
use skill tool to list skills
```
### Loading a Skill
Use the `use_skill` tool to load a specific skill:
Use OpenCode's native `skill` tool to load a specific skill:
```
use use_skill tool with skill_name: "superpowers:brainstorming"
use skill tool to load superpowers/brainstorming
```
### Personal Skills
@@ -69,36 +78,11 @@ description: Use when [condition] - [what it does]
[Your skill content here]
```
Personal skills override superpowers skills with the same name.
### Project Skills
Create project-specific skills in your OpenCode project:
Create project-specific skills in `.opencode/skills/` within your project.
```bash
# In your OpenCode project
mkdir -p .opencode/skills/my-project-skill
```
Create `.opencode/skills/my-project-skill/SKILL.md`:
```markdown
---
name: my-project-skill
description: Use when [condition] - [what it does]
---
# My Project Skill
[Your skill content here]
```
**Skill Priority:** Project skills override personal skills, which override superpowers skills.
**Skill Naming:**
- `project:skill-name` - Force project skill lookup
- `skill-name` - Searches project → personal → superpowers
- `superpowers:skill-name` - Force superpowers skill lookup
**Skill Priority:** Project skills > Personal skills > Superpowers skills
## Updating
@@ -111,25 +95,25 @@ git pull
### 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`
1. Check plugin symlink: `ls -l ~/.config/opencode/plugins/superpowers.js`
2. Check source exists: `ls ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
3. Check OpenCode logs for errors
### 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
1. Check skills symlink: `ls -l ~/.config/opencode/skills/superpowers`
2. Verify it points to: `~/.config/opencode/superpowers/skills`
3. Use `skill` tool to list what's discovered
### Tool mapping issues
### Tool mapping
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
When skills reference Claude Code tools:
- `TodoWrite``update_plan`
- `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
- Documentation: https://github.com/obra/superpowers
- Full documentation: https://github.com/obra/superpowers/blob/main/docs/README.opencode.md

View File

@@ -1,215 +0,0 @@
/**
* Superpowers plugin for OpenCode.ai
*
* Provides custom tools for loading and discovering skills,
* with prompt generation for agent configuration.
*/
import path from 'path';
import fs from 'fs';
import os from 'os';
import { fileURLToPath } from 'url';
import { tool } from '@opencode-ai/plugin/tool';
import * as skillsCore from '../../lib/skills-core.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export const SuperpowersPlugin = async ({ client, directory }) => {
const homeDir = os.homedir();
const projectSkillsDir = path.join(directory, '.opencode/skills');
// Derive superpowers skills dir from plugin location (works for both symlinked and local installs)
const superpowersSkillsDir = path.resolve(__dirname, '../../skills');
const personalSkillsDir = path.join(homeDir, '.config/opencode/skills');
// Helper to generate bootstrap content
const getBootstrapContent = (compact = false) => {
const usingSuperpowersPath = skillsCore.resolveSkillPath('using-superpowers', superpowersSkillsDir, personalSkillsDir);
if (!usingSuperpowersPath) return null;
const fullContent = fs.readFileSync(usingSuperpowersPath.skillFile, 'utf8');
const content = skillsCore.stripFrontmatter(fullContent);
const toolMapping = compact
? `**Tool Mapping:** TodoWrite->update_plan, Task->@mention, Skill->use_skill
**Skills naming (priority order):** project: > personal > superpowers:`
: `**Tool Mapping for OpenCode:**
When skills reference tools you don't have, substitute OpenCode equivalents:
- \`TodoWrite\`\`update_plan\`
- \`Task\` tool with subagents → Use OpenCode's subagent system (@mention)
- \`Skill\` tool → \`use_skill\` custom tool
- \`Read\`, \`Write\`, \`Edit\`, \`Bash\` → Your native tools
**Skills naming (priority order):**
- Project skills: \`project:skill-name\` (in .opencode/skills/)
- Personal skills: \`skill-name\` (in ~/.config/opencode/skills/)
- Superpowers skills: \`superpowers:skill-name\`
- Project skills override personal, which override superpowers when names match`;
return `<EXTREMELY_IMPORTANT>
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 use_skill tool to load "using-superpowers" - that would be redundant. Use use_skill only for OTHER skills.**
${content}
${toolMapping}
</EXTREMELY_IMPORTANT>`;
};
// Helper to inject bootstrap via session.prompt
const injectBootstrap = async (sessionID, compact = false) => {
const bootstrapContent = getBootstrapContent(compact);
if (!bootstrapContent) return false;
try {
await client.session.prompt({
path: { id: sessionID },
body: {
noReply: true,
parts: [{ type: "text", text: bootstrapContent, synthetic: true }]
}
});
return true;
} catch (err) {
return false;
}
};
return {
tool: {
use_skill: tool({
description: 'Load and read a specific skill to guide your work. Skills contain proven workflows, mandatory processes, and expert techniques.',
args: {
skill_name: tool.schema.string().describe('Name of the skill to load (e.g., "superpowers:brainstorming", "my-custom-skill", or "project:my-skill")')
},
execute: async (args, context) => {
const { skill_name } = args;
// Resolve with priority: project > personal > superpowers
// Check for project: prefix first
const forceProject = skill_name.startsWith('project:');
const actualSkillName = forceProject ? skill_name.replace(/^project:/, '') : skill_name;
let resolved = null;
// Try project skills first (if project: prefix or no prefix)
if (forceProject || !skill_name.startsWith('superpowers:')) {
const projectPath = path.join(projectSkillsDir, actualSkillName);
const projectSkillFile = path.join(projectPath, 'SKILL.md');
if (fs.existsSync(projectSkillFile)) {
resolved = {
skillFile: projectSkillFile,
sourceType: 'project',
skillPath: actualSkillName
};
}
}
// Fall back to personal/superpowers resolution
if (!resolved && !forceProject) {
resolved = skillsCore.resolveSkillPath(skill_name, superpowersSkillsDir, personalSkillsDir);
}
if (!resolved) {
return `Error: Skill "${skill_name}" not found.\n\nRun find_skills to see available skills.`;
}
const fullContent = fs.readFileSync(resolved.skillFile, 'utf8');
const { name, description } = skillsCore.extractFrontmatter(resolved.skillFile);
const content = skillsCore.stripFrontmatter(fullContent);
const skillDirectory = path.dirname(resolved.skillFile);
const skillHeader = `# ${name || skill_name}
# ${description || ''}
# Supporting tools and docs are in ${skillDirectory}
# ============================================`;
// Insert as user message with noReply for persistence across compaction
try {
await client.session.prompt({
path: { id: context.sessionID },
body: {
noReply: true,
parts: [
{ type: "text", text: `Loading skill: ${name || skill_name}`, synthetic: true },
{ type: "text", text: `${skillHeader}\n\n${content}`, synthetic: true }
]
}
});
} catch (err) {
// Fallback: return content directly if message insertion fails
return `${skillHeader}\n\n${content}`;
}
return `Launching skill: ${name || skill_name}`;
}
}),
find_skills: tool({
description: 'List all available skills in the project, personal, and superpowers skill libraries.',
args: {},
execute: async (args, context) => {
const projectSkills = skillsCore.findSkillsInDir(projectSkillsDir, 'project', 3);
const personalSkills = skillsCore.findSkillsInDir(personalSkillsDir, 'personal', 3);
const superpowersSkills = skillsCore.findSkillsInDir(superpowersSkillsDir, 'superpowers', 3);
// Priority: project > personal > superpowers
const allSkills = [...projectSkills, ...personalSkills, ...superpowersSkills];
if (allSkills.length === 0) {
return 'No skills found. Install superpowers skills to ~/.config/opencode/superpowers/skills/ or add project skills to .opencode/skills/';
}
let output = 'Available skills:\n\n';
for (const skill of allSkills) {
let namespace;
switch (skill.sourceType) {
case 'project':
namespace = 'project:';
break;
case 'personal':
namespace = '';
break;
default:
namespace = '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;
}
})
},
event: async ({ event }) => {
// Extract sessionID from various event structures
const getSessionID = () => {
return event.properties?.info?.id ||
event.properties?.sessionID ||
event.session?.id;
};
// Inject bootstrap at session creation (before first user message)
if (event.type === 'session.created') {
const sessionID = getSessionID();
if (sessionID) {
await injectBootstrap(sessionID, false);
}
}
// Re-inject bootstrap after context compaction (compact version to save tokens)
if (event.type === 'session.compacted') {
const sessionID = getSessionID();
if (sessionID) {
await injectBootstrap(sessionID, true);
}
}
}
};
};

View File

@@ -0,0 +1,95 @@
/**
* Superpowers plugin for OpenCode.ai
*
* Injects superpowers bootstrap context via system prompt transform.
* Skills are discovered via OpenCode's native skill tool from symlinked directory.
*/
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\`\`update_plan\`
- \`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 `<EXTREMELY_IMPORTANT>
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}
</EXTREMELY_IMPORTANT>`;
};
return {
// 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);
}
}
};
};

View File

@@ -44,18 +44,7 @@ Then install the plugin from this marketplace:
### Verify Installation
Check that commands appear:
```bash
/help
```
```
# Should see:
# /superpowers:brainstorm - Interactive design refinement
# /superpowers:write-plan - Create implementation plan
# /superpowers:execute-plan - Execute plan in batches
```
Start a new session and ask Claude to help with something that would trigger a skill (e.g., "help me plan this feature" or "let's debug this issue"). Claude should automatically invoke the relevant superpowers skill.
### Codex

View File

@@ -1,5 +1,116 @@
# Superpowers Release Notes
## Unreleased
### 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
**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).
**Windows: SessionStart hook runs async to prevent terminal freeze**
The synchronous SessionStart hook blocked the TUI from entering raw mode on Windows, freezing terminal input. The pure-bash `escape_for_json` function is O(n^2) on Windows Git Bash, taking 60+ seconds. Running the hook async prevents the freeze while still injecting superpowers context.
### New Features
**Visual companion for brainstorming skill**
Added optional browser-based visual companion for brainstorming sessions. When users have a browser available, brainstorming can display interactive screens showing current phase, questions, and design decisions in a more readable format than terminal output.
Components:
- `lib/brainstorm-server/` - WebSocket server for real-time updates
- `skills/brainstorming/visual-companion.md` - Integration guide
- Helper scripts for session management with proper isolation
- Browser helper library for event capture
The visual companion is opt-in and falls back gracefully to terminal-only operation.
### Improvements
**Instruction priority clarified in using-superpowers**
Added explicit instruction priority hierarchy to prevent conflicts with user preferences:
1. User's explicit instructions (CLAUDE.md, direct requests) — highest priority
2. Superpowers skills — override default system behavior where they conflict
3. Default system prompt — lowest priority
This ensures users remain in control. If CLAUDE.md says "don't use TDD" and a skill says "always use TDD," CLAUDE.md wins.
---
## 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

View File

@@ -1,6 +1,6 @@
# Superpowers for Codex
Complete guide for using Superpowers with OpenAI Codex.
Guide for using Superpowers with OpenAI Codex via native skill discovery.
## Quick Install
@@ -14,63 +14,59 @@ Fetch and follow instructions from https://raw.githubusercontent.com/obra/superp
### Prerequisites
- OpenAI Codex access
- Shell access to install files
- OpenAI Codex CLI
- Git
### Installation Steps
### Steps
#### 1. Clone Superpowers
1. Clone the repo:
```bash
git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
```
```bash
mkdir -p ~/.codex/superpowers
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.
### 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"
```
#### 2. Install Bootstrap
## How It Works
The bootstrap file is included in the repository at `.codex/superpowers-bootstrap.md`. Codex will automatically use it from the cloned location.
#### 3. Verify Installation
Tell Codex:
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:
```
Run ~/.codex/superpowers/.codex/superpowers-codex find-skills to show available skills
~/.agents/skills/superpowers/ → ~/.codex/superpowers/skills/
```
You should see a list of available skills with descriptions.
The `using-superpowers` skill is discovered automatically and enforces skill usage discipline — no additional configuration needed.
## Usage
### Finding Skills
```
Run ~/.codex/superpowers/.codex/superpowers-codex find-skills
```
### Loading a Skill
```
Run ~/.codex/superpowers/.codex/superpowers-codex use-skill superpowers:brainstorming
```
### Bootstrap All Skills
```
Run ~/.codex/superpowers/.codex/superpowers-codex bootstrap
```
This loads the complete bootstrap with all skill information.
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 `~/.codex/skills/`:
Create your own skills in `~/.agents/skills/`:
```bash
mkdir -p ~/.codex/skills/my-skill
mkdir -p ~/.agents/skills/my-skill
```
Create `~/.codex/skills/my-skill/SKILL.md`:
Create `~/.agents/skills/my-skill/SKILL.md`:
```markdown
---
@@ -83,71 +79,42 @@ description: Use when [condition] - [what it does]
[Your skill content here]
```
Personal skills override superpowers skills with the same name.
## Architecture
### Codex CLI Tool
**Location:** `~/.codex/superpowers/.codex/superpowers-codex`
A Node.js CLI script that provides three commands:
- `bootstrap` - Load complete bootstrap with all skills
- `use-skill <name>` - Load a specific skill
- `find-skills` - List all available skills
### Shared Core Module
**Location:** `~/.codex/superpowers/lib/skills-core.js`
The Codex implementation uses the shared `skills-core` module (ES module format) for skill discovery and parsing. This is the same module used by the OpenCode plugin, ensuring consistent behavior across platforms.
### Tool Mapping
Skills written for Claude Code are adapted for Codex with these mappings:
- `TodoWrite``update_plan`
- `Task` with subagents → Tell user subagents aren't available, do work directly
- `Skill` tool → `~/.codex/superpowers/.codex/superpowers-codex use-skill`
- File operations → Native Codex tools
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
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 found
### Skills not showing up
1. Verify installation: `ls ~/.codex/superpowers/skills`
2. Check CLI works: `~/.codex/superpowers/.codex/superpowers-codex find-skills`
3. Verify skills have SKILL.md files
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
### CLI script not executable
### Windows junction issues
```bash
chmod +x ~/.codex/superpowers/.codex/superpowers-codex
```
### Node.js errors
The CLI script requires Node.js. Verify:
```bash
node --version
```
Should show v14 or higher (v18+ recommended for ES module support).
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
- Blog post: https://blog.fsck.com/2025/10/27/skills-for-openai-codex/
## Note
Codex support is experimental and may require refinement based on user feedback. If you encounter issues, please report them on GitHub.

View File

@@ -7,7 +7,7 @@ Complete guide for using Superpowers with [OpenCode.ai](https://opencode.ai).
Tell OpenCode:
```
Clone https://github.com/obra/superpowers to ~/.config/opencode/superpowers, then create directory ~/.config/opencode/plugin, then symlink ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js to ~/.config/opencode/plugin/superpowers.js, then restart opencode.
Clone https://github.com/obra/superpowers to ~/.config/opencode/superpowers, then create directory ~/.config/opencode/plugins, then symlink ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js to ~/.config/opencode/plugins/superpowers.js, then symlink ~/.config/opencode/superpowers/skills to ~/.config/opencode/skills/superpowers, then restart opencode.
```
## Manual Installation
@@ -15,59 +15,175 @@ Clone https://github.com/obra/superpowers to ~/.config/opencode/superpowers, the
### Prerequisites
- [OpenCode.ai](https://opencode.ai) installed
- Node.js installed
- Git installed
### Installation Steps
#### 1. Install Superpowers
### macOS / Linux
```bash
mkdir -p ~/.config/opencode/superpowers
# 1. Install Superpowers (or update existing)
if [ -d ~/.config/opencode/superpowers ]; then
cd ~/.config/opencode/superpowers && git pull
else
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
fi
# 2. Create directories
mkdir -p ~/.config/opencode/plugins ~/.config/opencode/skills
# 3. Remove old symlinks/directories if they exist
rm -f ~/.config/opencode/plugins/superpowers.js
rm -rf ~/.config/opencode/skills/superpowers
# 4. Create symlinks
ln -s ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js ~/.config/opencode/plugins/superpowers.js
ln -s ~/.config/opencode/superpowers/skills ~/.config/opencode/skills/superpowers
# 5. Restart OpenCode
```
#### Verify Installation
```bash
ls -l ~/.config/opencode/plugins/superpowers.js
ls -l ~/.config/opencode/skills/superpowers
```
Both should show symlinks pointing to the superpowers directory.
### Windows
**Prerequisites:**
- Git installed
- Either **Developer Mode** enabled OR **Administrator privileges**
- Windows 10: Settings → Update & Security → For developers
- Windows 11: Settings → System → For developers
Pick your shell below: [Command Prompt](#command-prompt) | [PowerShell](#powershell) | [Git Bash](#git-bash)
#### Command Prompt
Run as Administrator, or with Developer Mode enabled:
```cmd
:: 1. Install Superpowers
git clone https://github.com/obra/superpowers.git "%USERPROFILE%\.config\opencode\superpowers"
:: 2. Create directories
mkdir "%USERPROFILE%\.config\opencode\plugins" 2>nul
mkdir "%USERPROFILE%\.config\opencode\skills" 2>nul
:: 3. Remove existing links (safe for reinstalls)
del "%USERPROFILE%\.config\opencode\plugins\superpowers.js" 2>nul
rmdir "%USERPROFILE%\.config\opencode\skills\superpowers" 2>nul
:: 4. Create plugin symlink (requires Developer Mode or Admin)
mklink "%USERPROFILE%\.config\opencode\plugins\superpowers.js" "%USERPROFILE%\.config\opencode\superpowers\.opencode\plugins\superpowers.js"
:: 5. Create skills junction (works without special privileges)
mklink /J "%USERPROFILE%\.config\opencode\skills\superpowers" "%USERPROFILE%\.config\opencode\superpowers\skills"
:: 6. Restart OpenCode
```
#### PowerShell
Run as Administrator, or with Developer Mode enabled:
```powershell
# 1. Install Superpowers
git clone https://github.com/obra/superpowers.git "$env:USERPROFILE\.config\opencode\superpowers"
# 2. Create directories
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode\plugins"
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode\skills"
# 3. Remove existing links (safe for reinstalls)
Remove-Item "$env:USERPROFILE\.config\opencode\plugins\superpowers.js" -Force -ErrorAction SilentlyContinue
Remove-Item "$env:USERPROFILE\.config\opencode\skills\superpowers" -Force -ErrorAction SilentlyContinue
# 4. Create plugin symlink (requires Developer Mode or Admin)
New-Item -ItemType SymbolicLink -Path "$env:USERPROFILE\.config\opencode\plugins\superpowers.js" -Target "$env:USERPROFILE\.config\opencode\superpowers\.opencode\plugins\superpowers.js"
# 5. Create skills junction (works without special privileges)
New-Item -ItemType Junction -Path "$env:USERPROFILE\.config\opencode\skills\superpowers" -Target "$env:USERPROFILE\.config\opencode\superpowers\skills"
# 6. Restart OpenCode
```
#### Git Bash
Note: Git Bash's native `ln` command copies files instead of creating symlinks. Use `cmd //c mklink` instead (the `//c` is Git Bash syntax for `/c`).
```bash
# 1. Install Superpowers
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
# 2. Create directories
mkdir -p ~/.config/opencode/plugins ~/.config/opencode/skills
# 3. Remove existing links (safe for reinstalls)
rm -f ~/.config/opencode/plugins/superpowers.js 2>/dev/null
rm -rf ~/.config/opencode/skills/superpowers 2>/dev/null
# 4. Create plugin symlink (requires Developer Mode or Admin)
cmd //c "mklink \"$(cygpath -w ~/.config/opencode/plugins/superpowers.js)\" \"$(cygpath -w ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js)\""
# 5. Create skills junction (works without special privileges)
cmd //c "mklink /J \"$(cygpath -w ~/.config/opencode/skills/superpowers)\" \"$(cygpath -w ~/.config/opencode/superpowers/skills)\""
# 6. Restart OpenCode
```
#### 2. Register the Plugin
#### WSL Users
OpenCode discovers plugins from `~/.config/opencode/plugin/`. Create a symlink:
If running OpenCode inside WSL, use the [macOS / Linux](#macos--linux) instructions instead.
```bash
mkdir -p ~/.config/opencode/plugin
ln -sf ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js ~/.config/opencode/plugin/superpowers.js
#### Verify Installation
**Command Prompt:**
```cmd
dir /AL "%USERPROFILE%\.config\opencode\plugins"
dir /AL "%USERPROFILE%\.config\opencode\skills"
```
Alternatively, for project-local installation:
```bash
# In your OpenCode project
mkdir -p .opencode/plugin
ln -sf ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js .opencode/plugin/superpowers.js
**PowerShell:**
```powershell
Get-ChildItem "$env:USERPROFILE\.config\opencode\plugins" | Where-Object { $_.LinkType }
Get-ChildItem "$env:USERPROFILE\.config\opencode\skills" | Where-Object { $_.LinkType }
```
#### 3. Restart OpenCode
Look for `<SYMLINK>` or `<JUNCTION>` in the output.
Restart OpenCode to load the plugin. Superpowers will automatically activate.
#### Troubleshooting Windows
**"You do not have sufficient privilege" error:**
- Enable Developer Mode in Windows Settings, OR
- Right-click your terminal → "Run as Administrator"
**"Cannot create a file when that file already exists":**
- Run the removal commands (step 3) first, then retry
**Symlinks not working after git clone:**
- Run `git config --global core.symlinks true` and re-clone
## Usage
### Finding Skills
Use the `find_skills` tool to list all available skills:
Use OpenCode's native `skill` tool to list all available skills:
```
use find_skills tool
use skill tool to list skills
```
### Loading a Skill
Use the `use_skill` tool to load a specific skill:
Use OpenCode's native `skill` tool to load a specific skill:
```
use use_skill tool with skill_name: "superpowers:brainstorming"
use skill tool to load superpowers/brainstorming
```
Skills are automatically inserted into the conversation and persist across context compaction.
### Personal Skills
Create your own skills in `~/.config/opencode/skills/`:
@@ -111,66 +227,48 @@ description: Use when [condition] - [what it does]
[Your skill content here]
```
## Skill Priority
## Skill Locations
Skills are resolved with this priority order:
OpenCode discovers skills from these locations:
1. **Project skills** (`.opencode/skills/`) - Highest priority
2. **Personal skills** (`~/.config/opencode/skills/`)
3. **Superpowers skills** (`~/.config/opencode/superpowers/skills/`)
You can force resolution to a specific level:
- `project:skill-name` - Force project skill
- `skill-name` - Search project → personal → superpowers
- `superpowers:skill-name` - Force superpowers skill
3. **Superpowers skills** (`~/.config/opencode/skills/superpowers/`) - via symlink
## Features
### Automatic Context Injection
The plugin automatically injects superpowers context via the chat.message hook on every session. No manual configuration needed.
The plugin automatically injects superpowers context via the `experimental.chat.system.transform` hook. This adds the "using-superpowers" skill content to the system prompt on every request.
### Message Insertion Pattern
### Native Skills Integration
When you load a skill with `use_skill`, it's inserted as a user message with `noReply: true`. This ensures skills persist throughout long conversations, even when OpenCode compacts context.
### Compaction Resilience
The plugin listens for `session.compacted` events and automatically re-injects the core superpowers bootstrap to maintain functionality after context compaction.
Superpowers uses OpenCode's native `skill` tool for skill discovery and loading. Skills are symlinked into `~/.config/opencode/skills/superpowers/` so they appear alongside your personal and project skills.
### Tool Mapping
Skills written for Claude Code are automatically adapted for OpenCode. The plugin provides mapping instructions:
Skills written for Claude Code are automatically adapted for OpenCode. The bootstrap provides mapping instructions:
- `TodoWrite``update_plan`
- `Task` with subagents → OpenCode's `@mention` system
- `Skill` tool → `use_skill` custom tool
- `Skill` tool → OpenCode's native `skill` tool
- File operations → Native OpenCode tools
## Architecture
### Plugin Structure
**Location:** `~/.config/opencode/superpowers/.opencode/plugin/superpowers.js`
**Location:** `~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
**Components:**
- Two custom tools: `use_skill`, `find_skills`
- chat.message hook for initial context injection
- event handler for session.compacted re-injection
- Uses shared `lib/skills-core.js` module (also used by Codex)
- `experimental.chat.system.transform` hook for bootstrap injection
- Reads and injects the "using-superpowers" skill content
### Shared Core Module
### Skills
**Location:** `~/.config/opencode/superpowers/lib/skills-core.js`
**Location:** `~/.config/opencode/skills/superpowers/` (symlink to `~/.config/opencode/superpowers/skills/`)
**Functions:**
- `extractFrontmatter()` - Parse skill metadata
- `stripFrontmatter()` - Remove metadata from content
- `findSkillsInDir()` - Recursive skill discovery
- `resolveSkillPath()` - Skill resolution with shadowing
- `checkForUpdates()` - Git update detection
This module is shared between OpenCode and Codex implementations for code reuse.
Skills are discovered by OpenCode's native skill system. Each skill has a `SKILL.md` file with YAML frontmatter.
## Updating
@@ -185,28 +283,28 @@ Restart OpenCode to load the updates.
### Plugin not loading
1. Check plugin file exists: `ls ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js`
2. Check symlink: `ls -l ~/.config/opencode/plugin/superpowers.js`
1. Check plugin exists: `ls ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
2. Check symlink/junction: `ls -l ~/.config/opencode/plugins/` (macOS/Linux) or `dir /AL %USERPROFILE%\.config\opencode\plugins` (Windows)
3. Check OpenCode logs: `opencode run "test" --print-logs --log-level DEBUG`
4. Look for: `service=plugin path=file:///.../superpowers.js loading plugin`
4. Look for plugin loading message in logs
### Skills not found
1. Verify skills directory: `ls ~/.config/opencode/superpowers/skills`
2. Use `find_skills` tool to see what's discovered
3. Check skill structure: each skill needs a `SKILL.md` file
1. Verify skills symlink: `ls -l ~/.config/opencode/skills/superpowers` (should point to superpowers/skills/)
2. Use OpenCode's `skill` tool to list available skills
3. Check skill structure: each skill needs a `SKILL.md` file with valid frontmatter
### Tools not working
### Windows: Module not found error
1. Verify plugin loaded: Check OpenCode logs for plugin loading message
2. Check Node.js version: The plugin requires Node.js for ES modules
3. Test plugin manually: `node --input-type=module -e "import('file://~/.config/opencode/plugin/superpowers.js').then(m => console.log(Object.keys(m)))"`
If you see `Cannot find module` errors on Windows:
- **Cause:** Git Bash `ln -sf` copies files instead of creating symlinks
- **Fix:** Use `mklink /J` directory junctions instead (see Windows installation steps)
### Context not injecting
### Bootstrap not appearing
1. Check if chat.message hook is working
2. Verify using-superpowers skill exists
3. Check OpenCode version (requires recent version with plugin support)
1. Verify using-superpowers skill exists: `ls ~/.config/opencode/superpowers/skills/using-superpowers/SKILL.md`
2. Check OpenCode version supports `experimental.chat.system.transform` hook
3. Restart OpenCode after plugin changes
## Getting Help
@@ -216,19 +314,17 @@ Restart OpenCode to load the updates.
## Testing
The implementation includes an automated test suite at `tests/opencode/`:
Verify your installation:
```bash
# Run all tests
./tests/opencode/run-tests.sh --integration --verbose
# Check plugin loads
opencode run --print-logs "hello" 2>&1 | grep -i superpowers
# Run specific test
./tests/opencode/run-tests.sh --test test-tools.sh
# Check skills are discoverable
opencode run "use skill tool to list all skills" 2>&1 | grep -i superpowers
# Check bootstrap injection
opencode run "what superpowers do you have?"
```
Tests verify:
- Plugin loading
- Skills-core library functionality
- Tool execution (use_skill, find_skills)
- Skill priority resolution
- Proper isolation with temp HOME
The agent should mention having superpowers and be able to list skills from `superpowers/`.

View File

@@ -6,7 +6,8 @@
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start.sh"
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh",
"async": true
}
]
}

View File

@@ -1,6 +1,30 @@
: << 'CMDBLOCK'
@echo off
REM Polyglot wrapper: runs .sh scripts cross-platform
REM ============================================================================
REM DEPRECATED: This polyglot wrapper is no longer used as of Claude Code 2.1.x
REM ============================================================================
REM
REM Claude Code 2.1.x changed the Windows execution model for hooks:
REM
REM Before (2.0.x): Hooks ran with shell:true, using the system default shell.
REM This wrapper provided cross-platform compatibility by
REM being both a valid .cmd file (Windows) and bash script.
REM
REM After (2.1.x): Claude Code now auto-detects .sh files in hook commands
REM and prepends "bash " on Windows. This broke the wrapper
REM because the command:
REM "run-hook.cmd" session-start.sh
REM became:
REM bash "run-hook.cmd" session-start.sh
REM ...and bash cannot execute a .cmd file.
REM
REM The fix: hooks.json now calls session-start.sh directly. Claude Code 2.1.x
REM handles the bash invocation automatically on Windows.
REM
REM This file is kept for reference and potential backward compatibility.
REM ============================================================================
REM
REM Original purpose: Polyglot wrapper to run .sh scripts cross-platform
REM Usage: run-hook.cmd <script-name> [args...]
REM The script should be in the same directory as this wrapper

View File

@@ -17,23 +17,17 @@ fi
# Read using-superpowers content
using_superpowers_content=$(cat "${PLUGIN_ROOT}/skills/using-superpowers/SKILL.md" 2>&1 || echo "Error reading using-superpowers skill")
# Escape outputs for JSON using pure bash
# Escape string for JSON embedding using bash parameter substitution.
# Each ${s//old/new} is a single C-level pass - orders of magnitude
# faster than the character-by-character loop this replaces.
escape_for_json() {
local input="$1"
local output=""
local i char
for (( i=0; i<${#input}; i++ )); do
char="${input:$i:1}"
case "$char" in
$'\\') output+='\\' ;;
'"') output+='\"' ;;
$'\n') output+='\n' ;;
$'\r') output+='\r' ;;
$'\t') output+='\t' ;;
*) output+="$char" ;;
esac
done
printf '%s' "$output"
local s="$1"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//$'\n'/\\n}"
s="${s//$'\r'/\\r}"
s="${s//$'\t'/\\t}"
printf '%s' "$s"
}
using_superpowers_escaped=$(escape_for_json "$using_superpowers_content")

View File

@@ -74,3 +74,11 @@ After all tasks complete and verified:
- Reference skills when plan says to
- Between batches: just report and wait
- Stop when blocked, don't guess
- Never start implementation on main/master branch without explicit user consent
## Integration
**Required workflow skills:**
- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting
- **superpowers:writing-plans** - Creates the plan this skill executes
- **superpowers:finishing-a-development-branch** - Complete development after all tasks

View File

@@ -199,6 +199,7 @@ Done!
## Red Flags
**Never:**
- Start implementation on main/master branch without explicit user consent
- Skip reviews (spec compliance OR code quality)
- Proceed with unfixed issues
- Dispatch multiple implementation subagents in parallel (conflicts)
@@ -229,6 +230,7 @@ Done!
## Integration
**Required workflow skills:**
- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting
- **superpowers:writing-plans** - Creates the plan this skill executes
- **superpowers:requesting-code-review** - Code review template for reviewer subagents
- **superpowers:finishing-a-development-branch** - Complete development after all tasks

View File

@@ -210,8 +210,9 @@ Ready to implement auth feature
**Called by:**
- **brainstorming** (Phase 4) - REQUIRED when design is approved and implementation follows
- **subagent-driven-development** - REQUIRED before executing any tasks
- **executing-plans** - REQUIRED before executing any tasks
- Any skill needing isolated workspace
**Pairs with:**
- **finishing-a-development-branch** - REQUIRED for cleanup after work complete
- **executing-plans** or **subagent-driven-development** - Work happens in this worktree

View File

@@ -9,7 +9,7 @@ description: Use when creating new skills, editing existing skills, or verifying
**Writing skills IS Test-Driven Development applied to process documentation.**
**Personal skills live in agent-specific directories (`~/.claude/skills` for Claude Code, `~/.codex/skills` for Codex)**
**Personal skills live in agent-specific directories (`~/.claude/skills` for Claude Code, `~/.agents/skills/` for Codex)**
You write test cases (pressure scenarios with subagents), watch them fail (baseline behavior), write the skill (documentation), watch tests pass (agents comply), and refactor (close loopholes).

View File

@@ -14,7 +14,7 @@ echo "Test 1: Skill loading..."
output=$(run_claude "What is the subagent-driven-development skill? Describe its key steps briefly." 30)
if assert_contains "$output" "subagent-driven-development" "Skill is recognized"; then
if assert_contains "$output" "subagent-driven-development\|Subagent-Driven Development\|Subagent Driven" "Skill is recognized"; then
: # pass
else
exit 1
@@ -136,4 +136,30 @@ fi
echo ""
# Test 8: Verify worktree requirement
echo "Test 8: Worktree requirement..."
output=$(run_claude "What workflow skills are required before using subagent-driven-development? List any prerequisites or required skills." 30)
if assert_contains "$output" "using-git-worktrees\|worktree" "Mentions worktree requirement"; then
: # pass
else
exit 1
fi
echo ""
# Test 9: Verify main branch warning
echo "Test 9: Main branch red flag..."
output=$(run_claude "In subagent-driven-development, is it okay to start implementation directly on the main branch?" 30)
if assert_contains "$output" "worktree\|feature.*branch\|not.*main\|never.*main\|avoid.*main\|don't.*main\|consent\|permission" "Warns against main branch"; then
: # pass
else
exit 1
fi
echo ""
echo "=== All subagent-driven-development skill tests passed ==="

View File

@@ -18,13 +18,13 @@ cp -r "$REPO_ROOT/lib" "$HOME/.config/opencode/superpowers/"
cp -r "$REPO_ROOT/skills" "$HOME/.config/opencode/superpowers/"
# Copy plugin directory
mkdir -p "$HOME/.config/opencode/superpowers/.opencode/plugin"
cp "$REPO_ROOT/.opencode/plugin/superpowers.js" "$HOME/.config/opencode/superpowers/.opencode/plugin/"
mkdir -p "$HOME/.config/opencode/superpowers/.opencode/plugins"
cp "$REPO_ROOT/.opencode/plugins/superpowers.js" "$HOME/.config/opencode/superpowers/.opencode/plugins/"
# Register plugin via symlink
mkdir -p "$HOME/.config/opencode/plugin"
ln -sf "$HOME/.config/opencode/superpowers/.opencode/plugin/superpowers.js" \
"$HOME/.config/opencode/plugin/superpowers.js"
mkdir -p "$HOME/.config/opencode/plugins"
ln -sf "$HOME/.config/opencode/superpowers/.opencode/plugins/superpowers.js" \
"$HOME/.config/opencode/plugins/superpowers.js"
# Create test skills in different locations for testing
@@ -57,8 +57,8 @@ PROJECT_SKILL_MARKER_67890
EOF
echo "Setup complete: $TEST_HOME"
echo "Plugin installed to: $HOME/.config/opencode/superpowers/.opencode/plugin/superpowers.js"
echo "Plugin registered at: $HOME/.config/opencode/plugin/superpowers.js"
echo "Plugin installed to: $HOME/.config/opencode/superpowers/.opencode/plugins/superpowers.js"
echo "Plugin registered at: $HOME/.config/opencode/plugins/superpowers.js"
echo "Test project at: $TEST_HOME/test-project"
# Helper function for cleanup (call from tests or trap)

View File

@@ -15,15 +15,15 @@ trap cleanup_test_env EXIT
# Test 1: Verify plugin file exists and is registered
echo "Test 1: Checking plugin registration..."
if [ -L "$HOME/.config/opencode/plugin/superpowers.js" ]; then
if [ -L "$HOME/.config/opencode/plugins/superpowers.js" ]; then
echo " [PASS] Plugin symlink exists"
else
echo " [FAIL] Plugin symlink not found at $HOME/.config/opencode/plugin/superpowers.js"
echo " [FAIL] Plugin symlink not found at $HOME/.config/opencode/plugins/superpowers.js"
exit 1
fi
# Verify symlink target exists
if [ -f "$(readlink -f "$HOME/.config/opencode/plugin/superpowers.js")" ]; then
if [ -f "$(readlink -f "$HOME/.config/opencode/plugins/superpowers.js")" ]; then
echo " [PASS] Plugin symlink target exists"
else
echo " [FAIL] Plugin symlink target does not exist"
@@ -60,7 +60,7 @@ fi
# Test 5: Verify plugin JavaScript syntax (basic check)
echo "Test 5: Checking plugin JavaScript syntax..."
plugin_file="$HOME/.config/opencode/superpowers/.opencode/plugin/superpowers.js"
plugin_file="$HOME/.config/opencode/superpowers/.opencode/plugins/superpowers.js"
if node --check "$plugin_file" 2>/dev/null; then
echo " [PASS] Plugin JavaScript syntax is valid"
else