mirror of
https://github.com/obra/superpowers.git
synced 2026-05-01 22:59:05 +08:00
Compare commits
20 Commits
gs/plan-mo
...
opencode-n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d525598b32 | ||
|
|
6491a1d9cf | ||
|
|
06dcd150ad | ||
|
|
6354d817eb | ||
|
|
2b8814f7d9 | ||
|
|
b16369cae2 | ||
|
|
e9263c9754 | ||
|
|
de2e15242c | ||
|
|
70c2d06c4e | ||
|
|
b98afbd74f | ||
|
|
2a61167b02 | ||
|
|
94d5f4a817 | ||
|
|
209fcec3b9 | ||
|
|
fccb5b4b8f | ||
|
|
15d0f2a8f6 | ||
|
|
cc585ad4d5 | ||
|
|
7e86703081 | ||
|
|
c536926f03 | ||
|
|
333eaa3281 | ||
|
|
74a55c0bf4 |
@@ -9,7 +9,7 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "4.2.0",
|
"version": "4.0.3",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "4.2.0",
|
"version": "4.0.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
"email": "jesse@fsck.com"
|
"email": "jesse@fsck.com"
|
||||||
|
|||||||
@@ -1,67 +1,35 @@
|
|||||||
# Installing Superpowers for Codex
|
# Installing Superpowers for Codex
|
||||||
|
|
||||||
Enable superpowers skills in Codex via native skill discovery. Just clone and symlink.
|
Quick setup to enable superpowers skills in Codex.
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- Git
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. **Clone the superpowers repository:**
|
1. **Clone superpowers repository**:
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
|
mkdir -p ~/.codex/superpowers
|
||||||
|
cd ~/.codex/superpowers
|
||||||
|
git clone https://github.com/obra/superpowers.git .
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Create the skills symlink:**
|
2. **Create personal skills directory**:
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.agents/skills
|
mkdir -p ~/.codex/skills
|
||||||
ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Windows (PowerShell):**
|
3. **Update ~/.codex/AGENTS.md** to include this superpowers section:
|
||||||
```powershell
|
```markdown
|
||||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills"
|
## Superpowers System
|
||||||
cmd /c mklink /J "$env:USERPROFILE\.agents\skills\superpowers" "$env:USERPROFILE\.codex\superpowers\skills"
|
|
||||||
|
<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>
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Restart Codex** (quit and relaunch the CLI) to discover the skills.
|
## Verification
|
||||||
|
|
||||||
## 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
|
```bash
|
||||||
ls -la ~/.agents/skills/superpowers
|
~/.codex/superpowers/.codex/superpowers-codex bootstrap
|
||||||
```
|
```
|
||||||
|
|
||||||
You should see a symlink (or junction on Windows) pointing to your superpowers skills directory.
|
You should see skill listings and bootstrap instructions. The system is now ready for use.
|
||||||
|
|
||||||
## 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`.
|
|
||||||
33
.codex/superpowers-bootstrap.md
Normal file
33
.codex/superpowers-bootstrap.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# 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>
|
||||||
267
.codex/superpowers-codex
Executable file
267
.codex/superpowers-codex
Executable file
@@ -0,0 +1,267 @@
|
|||||||
|
#!/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;
|
||||||
|
}
|
||||||
18
.gitattributes
vendored
18
.gitattributes
vendored
@@ -1,18 +0,0 @@
|
|||||||
# 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
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,5 +2,3 @@
|
|||||||
.private-journal/
|
.private-journal/
|
||||||
.claude/
|
.claude/
|
||||||
node_modules/
|
node_modules/
|
||||||
inspo
|
|
||||||
triage/
|
|
||||||
|
|||||||
@@ -3,13 +3,15 @@
|
|||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- [OpenCode.ai](https://opencode.ai) installed
|
- [OpenCode.ai](https://opencode.ai) installed
|
||||||
|
- Node.js installed
|
||||||
- Git installed
|
- Git installed
|
||||||
|
|
||||||
## Installation Steps
|
## Installation Steps
|
||||||
|
|
||||||
### 1. Clone Superpowers
|
### 1. Install Superpowers
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
mkdir -p ~/.config/opencode/superpowers
|
||||||
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
|
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -18,43 +20,32 @@ git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
|
|||||||
Create a symlink so OpenCode discovers the plugin:
|
Create a symlink so OpenCode discovers the plugin:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.config/opencode/plugins
|
mkdir -p ~/.config/opencode/plugin
|
||||||
rm -f ~/.config/opencode/plugins/superpowers.js
|
ln -sf ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js ~/.config/opencode/plugin/superpowers.js
|
||||||
ln -s ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js ~/.config/opencode/plugins/superpowers.js
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Symlink Skills
|
### 3. Restart OpenCode
|
||||||
|
|
||||||
Create a symlink so OpenCode's native skill tool discovers superpowers skills:
|
Restart OpenCode. The plugin will automatically inject superpowers context via the chat.message hook.
|
||||||
|
|
||||||
```bash
|
You should see superpowers is active when you ask "do you have superpowers?"
|
||||||
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
|
## Usage
|
||||||
|
|
||||||
### Finding Skills
|
### Finding Skills
|
||||||
|
|
||||||
Use OpenCode's native `skill` tool to list available skills:
|
Use the `find_skills` tool to list all available skills:
|
||||||
|
|
||||||
```
|
```
|
||||||
use skill tool to list skills
|
use find_skills tool
|
||||||
```
|
```
|
||||||
|
|
||||||
### Loading a Skill
|
### Loading a Skill
|
||||||
|
|
||||||
Use OpenCode's native `skill` tool to load a specific skill:
|
Use the `use_skill` tool to load a specific skill:
|
||||||
|
|
||||||
```
|
```
|
||||||
use skill tool to load superpowers/brainstorming
|
use use_skill tool with skill_name: "superpowers:brainstorming"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Personal Skills
|
### Personal Skills
|
||||||
@@ -78,11 +69,36 @@ description: Use when [condition] - [what it does]
|
|||||||
[Your skill content here]
|
[Your skill content here]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Personal skills override superpowers skills with the same name.
|
||||||
|
|
||||||
### Project Skills
|
### Project Skills
|
||||||
|
|
||||||
Create project-specific skills in `.opencode/skills/` within your project.
|
Create project-specific skills in your OpenCode project:
|
||||||
|
|
||||||
**Skill Priority:** Project skills > Personal skills > Superpowers skills
|
```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
|
||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
|
|
||||||
@@ -95,25 +111,25 @@ git pull
|
|||||||
|
|
||||||
### Plugin not loading
|
### Plugin not loading
|
||||||
|
|
||||||
1. Check plugin symlink: `ls -l ~/.config/opencode/plugins/superpowers.js`
|
1. Check plugin file exists: `ls ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js`
|
||||||
2. Check source exists: `ls ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
|
2. Check OpenCode logs for errors
|
||||||
3. Check OpenCode logs for errors
|
3. Verify Node.js is installed: `node --version`
|
||||||
|
|
||||||
### Skills not found
|
### Skills not found
|
||||||
|
|
||||||
1. Check skills symlink: `ls -l ~/.config/opencode/skills/superpowers`
|
1. Verify skills directory exists: `ls ~/.config/opencode/superpowers/skills`
|
||||||
2. Verify it points to: `~/.config/opencode/superpowers/skills`
|
2. Use `find_skills` tool to see what's discovered
|
||||||
3. Use `skill` tool to list what's discovered
|
3. Check file structure: each skill should have a `SKILL.md` file
|
||||||
|
|
||||||
### Tool mapping
|
### Tool mapping issues
|
||||||
|
|
||||||
When skills reference Claude Code tools:
|
When a skill references a Claude Code tool you don't have:
|
||||||
- `TodoWrite` → `update_plan`
|
- `TodoWrite` → use `update_plan`
|
||||||
- `Task` with subagents → `@mention` syntax
|
- `Task` with subagents → use `@mention` syntax to invoke OpenCode subagents
|
||||||
- `Skill` tool → OpenCode's native `skill` tool
|
- `Skill` → use `use_skill` tool
|
||||||
- File operations → your native tools
|
- File operations → use your native tools
|
||||||
|
|
||||||
## Getting Help
|
## Getting Help
|
||||||
|
|
||||||
- Report issues: https://github.com/obra/superpowers/issues
|
- Report issues: https://github.com/obra/superpowers/issues
|
||||||
- Full documentation: https://github.com/obra/superpowers/blob/main/docs/README.opencode.md
|
- Documentation: https://github.com/obra/superpowers
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -44,7 +44,18 @@ Then install the plugin from this marketplace:
|
|||||||
|
|
||||||
### Verify Installation
|
### Verify Installation
|
||||||
|
|
||||||
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.
|
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
|
||||||
|
```
|
||||||
|
|
||||||
### Codex
|
### Codex
|
||||||
|
|
||||||
|
|||||||
155
RELEASE-NOTES.md
155
RELEASE-NOTES.md
@@ -4,25 +4,6 @@
|
|||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
|
||||||
**Specs and plans directory restructured**
|
|
||||||
|
|
||||||
- Specs (brainstorming output) now go to `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md`
|
|
||||||
- Plans (writing-plans output) now go to `docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md`
|
|
||||||
- User preferences for spec/plan locations override these defaults
|
|
||||||
- Migration: move existing files from `docs/plans/` to new locations if desired
|
|
||||||
|
|
||||||
**Brainstorming → writing-plans transition enforced**
|
|
||||||
|
|
||||||
- After design approval, brainstorming now requires using writing-plans skill
|
|
||||||
- Platform planning features (e.g., EnterPlanMode) should not be used
|
|
||||||
- Direct implementation without writing-plans is not allowed
|
|
||||||
|
|
||||||
**Subagent-driven development now mandatory on capable harnesses**
|
|
||||||
|
|
||||||
- On harnesses with subagent support (Claude Code), subagent-driven-development is now required after plan approval
|
|
||||||
- No longer offers a choice between subagent-driven and executing-plans
|
|
||||||
- Executing-plans is only used on harnesses without subagent capability
|
|
||||||
|
|
||||||
**OpenCode: Switched to native skills system**
|
**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.
|
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.
|
||||||
@@ -55,28 +36,6 @@ Components:
|
|||||||
|
|
||||||
The visual companion is opt-in and falls back gracefully to terminal-only operation.
|
The visual companion is opt-in and falls back gracefully to terminal-only operation.
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
**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).
|
|
||||||
|
|
||||||
**Brainstorming visual companion: reduced token cost and improved persistence**
|
|
||||||
|
|
||||||
The visual companion now generates much smaller HTML per screen. The server automatically wraps bare content fragments in the frame template (header, CSS theme, feedback footer, interactive JS), so Claude writes only the content portion (~30 lines instead of ~260). Full HTML documents are still served as-is when Claude needs complete control.
|
|
||||||
|
|
||||||
Other improvements:
|
|
||||||
- `toggleSelect`/`send`/`selectedChoice` moved from inline template script to `helper.js` (auto-injected)
|
|
||||||
- `start-server.sh --project-dir` persists mockups under `.superpowers/brainstorm/` instead of `/tmp`
|
|
||||||
- `stop-server.sh` only deletes ephemeral `/tmp` sessions, preserving persistent ones
|
|
||||||
- Dark mode fix: `sendToClaude` confirmation page now uses CSS variables instead of hardcoded colors
|
|
||||||
- Skill restructured: SKILL.md is minimal (prompt + pointer); all visual companion details in progressive disclosure doc (`visual-companion.md`)
|
|
||||||
- Prompt to user now notes the feature is new, token-intensive, and can be slow
|
|
||||||
- Deleted redundant `CLAUDE-INSTRUCTIONS.md` (content folded into `visual-companion.md`)
|
|
||||||
- Test fixes: correct env var (`BRAINSTORM_DIR`), polling-based startup wait, new tests for frame wrapping
|
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
**Instruction priority clarified in using-superpowers**
|
**Instruction priority clarified in using-superpowers**
|
||||||
@@ -89,120 +48,6 @@ Added explicit instruction priority hierarchy to prevent conflicts with user pre
|
|||||||
|
|
||||||
This ensures users remain in control. If CLAUDE.md says "don't use TDD" and a skill says "always use TDD," CLAUDE.md wins.
|
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.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)
|
## v4.0.3 (2025-12-26)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Superpowers for Codex
|
# Superpowers for Codex
|
||||||
|
|
||||||
Guide for using Superpowers with OpenAI Codex via native skill discovery.
|
Complete guide for using Superpowers with OpenAI Codex.
|
||||||
|
|
||||||
## Quick Install
|
## Quick Install
|
||||||
|
|
||||||
@@ -14,65 +14,63 @@ Fetch and follow instructions from https://raw.githubusercontent.com/obra/superp
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- OpenAI Codex CLI
|
- OpenAI Codex access
|
||||||
- Git
|
- Shell access to install files
|
||||||
|
|
||||||
### Steps
|
### Installation Steps
|
||||||
|
|
||||||
1. Clone the repo:
|
#### 1. Clone Superpowers
|
||||||
```bash
|
|
||||||
git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Create the skills symlink:
|
```bash
|
||||||
```bash
|
mkdir -p ~/.codex/superpowers
|
||||||
mkdir -p ~/.agents/skills
|
git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
|
||||||
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 collab feature. Add to your Codex config:
|
|
||||||
```toml
|
|
||||||
[features]
|
|
||||||
collab = 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
|
#### 2. Install Bootstrap
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
```
|
```
|
||||||
~/.agents/skills/superpowers/ → ~/.codex/superpowers/skills/
|
Run ~/.codex/superpowers/.codex/superpowers-codex find-skills to show available skills
|
||||||
```
|
```
|
||||||
|
|
||||||
The `using-superpowers` skill is discovered automatically and enforces skill usage discipline — no additional configuration needed.
|
You should see a list of available skills with descriptions.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Skills are discovered automatically. Codex activates them when:
|
### Finding Skills
|
||||||
- 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
|
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.
|
||||||
|
|
||||||
### Personal Skills
|
### Personal Skills
|
||||||
|
|
||||||
Create your own skills in `~/.agents/skills/`:
|
Create your own skills in `~/.codex/skills/`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.agents/skills/my-skill
|
mkdir -p ~/.codex/skills/my-skill
|
||||||
```
|
```
|
||||||
|
|
||||||
Create `~/.agents/skills/my-skill/SKILL.md`:
|
Create `~/.codex/skills/my-skill/SKILL.md`:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
---
|
---
|
||||||
@@ -85,42 +83,71 @@ description: Use when [condition] - [what it does]
|
|||||||
[Your skill content here]
|
[Your skill content here]
|
||||||
```
|
```
|
||||||
|
|
||||||
The `description` field is how Codex decides when to activate a skill automatically — write it as a clear trigger condition.
|
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
|
||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
|
|
||||||
```bash
|
```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
|
## Troubleshooting
|
||||||
|
|
||||||
### Skills not showing up
|
### Skills not found
|
||||||
|
|
||||||
1. Verify the symlink: `ls -la ~/.agents/skills/superpowers`
|
1. Verify installation: `ls ~/.codex/superpowers/skills`
|
||||||
2. Check skills exist: `ls ~/.codex/superpowers/skills`
|
2. Check CLI works: `~/.codex/superpowers/.codex/superpowers-codex find-skills`
|
||||||
3. Restart Codex — skills are discovered at startup
|
3. Verify skills have SKILL.md files
|
||||||
|
|
||||||
### Windows junction issues
|
### CLI script not executable
|
||||||
|
|
||||||
Junctions normally work without special permissions. If creation fails, try running PowerShell as administrator.
|
```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).
|
||||||
|
|
||||||
## Getting Help
|
## Getting Help
|
||||||
|
|
||||||
- Report issues: https://github.com/obra/superpowers/issues
|
- Report issues: https://github.com/obra/superpowers/issues
|
||||||
- Main documentation: https://github.com/obra/superpowers
|
- 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.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Complete guide for using Superpowers with [OpenCode.ai](https://opencode.ai).
|
|||||||
Tell OpenCode:
|
Tell 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.
|
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 symlink ~/.config/opencode/superpowers/skills to ~/.config/opencode/skills/superpowers, then restart opencode.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Manual Installation
|
## Manual Installation
|
||||||
@@ -28,23 +28,19 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Create directories
|
# 2. Create directories
|
||||||
mkdir -p ~/.config/opencode/plugins ~/.config/opencode/skills
|
mkdir -p ~/.config/opencode/plugin ~/.config/opencode/skills
|
||||||
|
|
||||||
# 3. Remove old symlinks/directories if they exist
|
# 3. Create symlinks (safe for reinstalls - ln -sf overwrites)
|
||||||
rm -f ~/.config/opencode/plugins/superpowers.js
|
ln -sf ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js ~/.config/opencode/plugin/superpowers.js
|
||||||
rm -rf ~/.config/opencode/skills/superpowers
|
ln -sf ~/.config/opencode/superpowers/skills ~/.config/opencode/skills/superpowers
|
||||||
|
|
||||||
# 4. Create symlinks
|
# 4. Restart OpenCode
|
||||||
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
|
#### Verify Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ls -l ~/.config/opencode/plugins/superpowers.js
|
ls -l ~/.config/opencode/plugin/superpowers.js
|
||||||
ls -l ~/.config/opencode/skills/superpowers
|
ls -l ~/.config/opencode/skills/superpowers
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -69,15 +65,15 @@ Run as Administrator, or with Developer Mode enabled:
|
|||||||
git clone https://github.com/obra/superpowers.git "%USERPROFILE%\.config\opencode\superpowers"
|
git clone https://github.com/obra/superpowers.git "%USERPROFILE%\.config\opencode\superpowers"
|
||||||
|
|
||||||
:: 2. Create directories
|
:: 2. Create directories
|
||||||
mkdir "%USERPROFILE%\.config\opencode\plugins" 2>nul
|
mkdir "%USERPROFILE%\.config\opencode\plugin" 2>nul
|
||||||
mkdir "%USERPROFILE%\.config\opencode\skills" 2>nul
|
mkdir "%USERPROFILE%\.config\opencode\skills" 2>nul
|
||||||
|
|
||||||
:: 3. Remove existing links (safe for reinstalls)
|
:: 3. Remove existing links (safe for reinstalls)
|
||||||
del "%USERPROFILE%\.config\opencode\plugins\superpowers.js" 2>nul
|
del "%USERPROFILE%\.config\opencode\plugin\superpowers.js" 2>nul
|
||||||
rmdir "%USERPROFILE%\.config\opencode\skills\superpowers" 2>nul
|
rmdir "%USERPROFILE%\.config\opencode\skills\superpowers" 2>nul
|
||||||
|
|
||||||
:: 4. Create plugin symlink (requires Developer Mode or Admin)
|
:: 4. Create plugin symlink (requires Developer Mode or Admin)
|
||||||
mklink "%USERPROFILE%\.config\opencode\plugins\superpowers.js" "%USERPROFILE%\.config\opencode\superpowers\.opencode\plugins\superpowers.js"
|
mklink "%USERPROFILE%\.config\opencode\plugin\superpowers.js" "%USERPROFILE%\.config\opencode\superpowers\.opencode\plugin\superpowers.js"
|
||||||
|
|
||||||
:: 5. Create skills junction (works without special privileges)
|
:: 5. Create skills junction (works without special privileges)
|
||||||
mklink /J "%USERPROFILE%\.config\opencode\skills\superpowers" "%USERPROFILE%\.config\opencode\superpowers\skills"
|
mklink /J "%USERPROFILE%\.config\opencode\skills\superpowers" "%USERPROFILE%\.config\opencode\superpowers\skills"
|
||||||
@@ -94,15 +90,15 @@ Run as Administrator, or with Developer Mode enabled:
|
|||||||
git clone https://github.com/obra/superpowers.git "$env:USERPROFILE\.config\opencode\superpowers"
|
git clone https://github.com/obra/superpowers.git "$env:USERPROFILE\.config\opencode\superpowers"
|
||||||
|
|
||||||
# 2. Create directories
|
# 2. Create directories
|
||||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode\plugins"
|
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode\plugin"
|
||||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode\skills"
|
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode\skills"
|
||||||
|
|
||||||
# 3. Remove existing links (safe for reinstalls)
|
# 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\plugin\superpowers.js" -Force -ErrorAction SilentlyContinue
|
||||||
Remove-Item "$env:USERPROFILE\.config\opencode\skills\superpowers" -Force -ErrorAction SilentlyContinue
|
Remove-Item "$env:USERPROFILE\.config\opencode\skills\superpowers" -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# 4. Create plugin symlink (requires Developer Mode or Admin)
|
# 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"
|
New-Item -ItemType SymbolicLink -Path "$env:USERPROFILE\.config\opencode\plugin\superpowers.js" -Target "$env:USERPROFILE\.config\opencode\superpowers\.opencode\plugin\superpowers.js"
|
||||||
|
|
||||||
# 5. Create skills junction (works without special privileges)
|
# 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"
|
New-Item -ItemType Junction -Path "$env:USERPROFILE\.config\opencode\skills\superpowers" -Target "$env:USERPROFILE\.config\opencode\superpowers\skills"
|
||||||
@@ -119,14 +115,14 @@ Note: Git Bash's native `ln` command copies files instead of creating symlinks.
|
|||||||
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
|
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
|
||||||
|
|
||||||
# 2. Create directories
|
# 2. Create directories
|
||||||
mkdir -p ~/.config/opencode/plugins ~/.config/opencode/skills
|
mkdir -p ~/.config/opencode/plugin ~/.config/opencode/skills
|
||||||
|
|
||||||
# 3. Remove existing links (safe for reinstalls)
|
# 3. Remove existing links (safe for reinstalls)
|
||||||
rm -f ~/.config/opencode/plugins/superpowers.js 2>/dev/null
|
rm -f ~/.config/opencode/plugin/superpowers.js 2>/dev/null
|
||||||
rm -rf ~/.config/opencode/skills/superpowers 2>/dev/null
|
rm -rf ~/.config/opencode/skills/superpowers 2>/dev/null
|
||||||
|
|
||||||
# 4. Create plugin symlink (requires Developer Mode or Admin)
|
# 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)\""
|
cmd //c "mklink \"$(cygpath -w ~/.config/opencode/plugin/superpowers.js)\" \"$(cygpath -w ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js)\""
|
||||||
|
|
||||||
# 5. Create skills junction (works without special privileges)
|
# 5. Create skills junction (works without special privileges)
|
||||||
cmd //c "mklink /J \"$(cygpath -w ~/.config/opencode/skills/superpowers)\" \"$(cygpath -w ~/.config/opencode/superpowers/skills)\""
|
cmd //c "mklink /J \"$(cygpath -w ~/.config/opencode/skills/superpowers)\" \"$(cygpath -w ~/.config/opencode/superpowers/skills)\""
|
||||||
@@ -142,13 +138,13 @@ If running OpenCode inside WSL, use the [macOS / Linux](#macos--linux) instructi
|
|||||||
|
|
||||||
**Command Prompt:**
|
**Command Prompt:**
|
||||||
```cmd
|
```cmd
|
||||||
dir /AL "%USERPROFILE%\.config\opencode\plugins"
|
dir /AL "%USERPROFILE%\.config\opencode\plugin"
|
||||||
dir /AL "%USERPROFILE%\.config\opencode\skills"
|
dir /AL "%USERPROFILE%\.config\opencode\skills"
|
||||||
```
|
```
|
||||||
|
|
||||||
**PowerShell:**
|
**PowerShell:**
|
||||||
```powershell
|
```powershell
|
||||||
Get-ChildItem "$env:USERPROFILE\.config\opencode\plugins" | Where-Object { $_.LinkType }
|
Get-ChildItem "$env:USERPROFILE\.config\opencode\plugin" | Where-Object { $_.LinkType }
|
||||||
Get-ChildItem "$env:USERPROFILE\.config\opencode\skills" | Where-Object { $_.LinkType }
|
Get-ChildItem "$env:USERPROFILE\.config\opencode\skills" | Where-Object { $_.LinkType }
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -258,7 +254,7 @@ Skills written for Claude Code are automatically adapted for OpenCode. The boots
|
|||||||
|
|
||||||
### Plugin Structure
|
### Plugin Structure
|
||||||
|
|
||||||
**Location:** `~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
|
**Location:** `~/.config/opencode/superpowers/.opencode/plugin/superpowers.js`
|
||||||
|
|
||||||
**Components:**
|
**Components:**
|
||||||
- `experimental.chat.system.transform` hook for bootstrap injection
|
- `experimental.chat.system.transform` hook for bootstrap injection
|
||||||
@@ -283,8 +279,8 @@ Restart OpenCode to load the updates.
|
|||||||
|
|
||||||
### Plugin not loading
|
### Plugin not loading
|
||||||
|
|
||||||
1. Check plugin exists: `ls ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
|
1. Check plugin exists: `ls ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js`
|
||||||
2. Check symlink/junction: `ls -l ~/.config/opencode/plugins/` (macOS/Linux) or `dir /AL %USERPROFILE%\.config\opencode\plugins` (Windows)
|
2. Check symlink/junction: `ls -l ~/.config/opencode/plugin/` (macOS/Linux) or `dir /AL %USERPROFILE%\.config\opencode\plugin` (Windows)
|
||||||
3. Check OpenCode logs: `opencode run "test" --print-logs --log-level DEBUG`
|
3. Check OpenCode logs: `opencode run "test" --print-logs --log-level DEBUG`
|
||||||
4. Look for plugin loading message in logs
|
4. Look for plugin loading message in logs
|
||||||
|
|
||||||
|
|||||||
@@ -1,301 +0,0 @@
|
|||||||
# Document Review System Implementation Plan
|
|
||||||
|
|
||||||
> **For Claude:** 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: <name>` 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 Claude:** 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 Claude:" 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"
|
|
||||||
```
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
# 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: <name>` 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
|
|
||||||
@@ -6,8 +6,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd session-start",
|
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start.sh"
|
||||||
"async": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,19 @@
|
|||||||
: << 'CMDBLOCK'
|
: << 'CMDBLOCK'
|
||||||
@echo off
|
@echo off
|
||||||
REM Cross-platform polyglot wrapper for hook scripts.
|
REM Polyglot wrapper: runs .sh scripts cross-platform
|
||||||
REM On Windows: cmd.exe runs the batch portion, which finds and calls bash.
|
|
||||||
REM On Unix: the shell interprets this as a script (: is a no-op in bash).
|
|
||||||
REM
|
|
||||||
REM Hook scripts use extensionless filenames (e.g. "session-start" not
|
|
||||||
REM "session-start.sh") so Claude Code's Windows auto-detection -- which
|
|
||||||
REM prepends "bash" to any command containing .sh -- doesn't interfere.
|
|
||||||
REM
|
|
||||||
REM Usage: run-hook.cmd <script-name> [args...]
|
REM Usage: run-hook.cmd <script-name> [args...]
|
||||||
|
REM The script should be in the same directory as this wrapper
|
||||||
|
|
||||||
if "%~1"=="" (
|
if "%~1"=="" (
|
||||||
echo run-hook.cmd: missing script name >&2
|
echo run-hook.cmd: missing script name >&2
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
"C:\Program Files\Git\bin\bash.exe" -l "%~dp0%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
||||||
set "HOOK_DIR=%~dp0"
|
exit /b
|
||||||
|
|
||||||
REM Try Git for Windows bash in standard locations
|
|
||||||
if exist "C:\Program Files\Git\bin\bash.exe" (
|
|
||||||
"C:\Program Files\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
||||||
exit /b %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
if exist "C:\Program Files (x86)\Git\bin\bash.exe" (
|
|
||||||
"C:\Program Files (x86)\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
||||||
exit /b %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
|
|
||||||
REM Try bash on PATH (e.g. user-installed Git Bash, MSYS2, Cygwin)
|
|
||||||
where bash >nul 2>nul
|
|
||||||
if %ERRORLEVEL% equ 0 (
|
|
||||||
bash "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
|
|
||||||
exit /b %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
|
|
||||||
REM No bash found - exit silently rather than error
|
|
||||||
REM (plugin still works, just without SessionStart context injection)
|
|
||||||
exit /b 0
|
|
||||||
CMDBLOCK
|
CMDBLOCK
|
||||||
|
|
||||||
# Unix: run the named script directly
|
# Unix shell runs from here
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
SCRIPT_NAME="$1"
|
SCRIPT_NAME="$1"
|
||||||
shift
|
shift
|
||||||
exec bash "${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
|
"${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
|
||||||
|
|||||||
@@ -17,17 +17,23 @@ fi
|
|||||||
# Read using-superpowers content
|
# Read using-superpowers content
|
||||||
using_superpowers_content=$(cat "${PLUGIN_ROOT}/skills/using-superpowers/SKILL.md" 2>&1 || echo "Error reading using-superpowers skill")
|
using_superpowers_content=$(cat "${PLUGIN_ROOT}/skills/using-superpowers/SKILL.md" 2>&1 || echo "Error reading using-superpowers skill")
|
||||||
|
|
||||||
# Escape string for JSON embedding using bash parameter substitution.
|
# Escape outputs for JSON using pure bash
|
||||||
# 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() {
|
escape_for_json() {
|
||||||
local s="$1"
|
local input="$1"
|
||||||
s="${s//\\/\\\\}"
|
local output=""
|
||||||
s="${s//\"/\\\"}"
|
local i char
|
||||||
s="${s//$'\n'/\\n}"
|
for (( i=0; i<${#input}; i++ )); do
|
||||||
s="${s//$'\r'/\\r}"
|
char="${input:$i:1}"
|
||||||
s="${s//$'\t'/\\t}"
|
case "$char" in
|
||||||
printf '%s' "$s"
|
$'\\') output+='\\' ;;
|
||||||
|
'"') output+='\"' ;;
|
||||||
|
$'\n') output+='\n' ;;
|
||||||
|
$'\r') output+='\r' ;;
|
||||||
|
$'\t') output+='\t' ;;
|
||||||
|
*) output+="$char" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
printf '%s' "$output"
|
||||||
}
|
}
|
||||||
|
|
||||||
using_superpowers_escaped=$(escape_for_json "$using_superpowers_content")
|
using_superpowers_escaped=$(escape_for_json "$using_superpowers_content")
|
||||||
212
lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md
Normal file
212
lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
# Visual Companion Instructions for Claude
|
||||||
|
|
||||||
|
This document explains how to use the brainstorm visual companion to show mockups, designs, and options to users without resorting to ASCII art.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use the visual companion when you need to show:
|
||||||
|
- **UI mockups** - layouts, navigation patterns, component designs
|
||||||
|
- **Design comparisons** - "Which of these 3 approaches works better?"
|
||||||
|
- **Interactive prototypes** - clickable wireframes
|
||||||
|
- **Visual choices** - anything where seeing beats describing
|
||||||
|
|
||||||
|
**Don't use it for:** simple text questions, code review, or when the user prefers terminal-only interaction.
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start server (returns JSON with URL and session directory)
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
|
||||||
|
# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
|
||||||
|
# "screen_dir":"/tmp/brainstorm-12345-1234567890"}
|
||||||
|
|
||||||
|
# Save screen_dir from response!
|
||||||
|
|
||||||
|
# Tell user to open the URL in their browser
|
||||||
|
|
||||||
|
# For each screen:
|
||||||
|
# 1. Start watcher in background FIRST (avoids race condition)
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-feedback.sh $SCREEN_DIR
|
||||||
|
# 2. Write HTML to a NEW file in screen_dir (e.g., platform.html, style.html)
|
||||||
|
# Server automatically serves the newest file by modification time
|
||||||
|
# 3. Call TaskOutput(task_id, block=true, timeout=600000) to wait for feedback
|
||||||
|
|
||||||
|
# When done, stop server (pass screen_dir)
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Naming
|
||||||
|
|
||||||
|
- **Use semantic names**: `platform.html`, `visual-style.html`, `layout.html`, `controls.html`
|
||||||
|
- **Never reuse filenames** - each screen must be a new file
|
||||||
|
- **For iterations**: append version suffix like `layout-v2.html`, `layout-v3.html`
|
||||||
|
- Server automatically serves the newest `.html` file by modification time
|
||||||
|
|
||||||
|
## Writing Screens
|
||||||
|
|
||||||
|
Copy the frame template structure but replace `#claude-content` with your content:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div id="claude-content">
|
||||||
|
<h2>Your Question</h2>
|
||||||
|
<p class="subtitle">Brief context</p>
|
||||||
|
|
||||||
|
<!-- Your content here -->
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
The frame template (`frame-template.html`) includes CSS for:
|
||||||
|
- OS-aware light/dark theming
|
||||||
|
- Fixed header and feedback footer
|
||||||
|
- Common UI patterns (see below)
|
||||||
|
|
||||||
|
## CSS Helper Classes
|
||||||
|
|
||||||
|
### Options (A/B/C choices)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="options">
|
||||||
|
<div class="option" data-choice="a" onclick="toggleSelect(this)">
|
||||||
|
<div class="letter">A</div>
|
||||||
|
<div class="content">
|
||||||
|
<h3>Option Title</h3>
|
||||||
|
<p>Description of this option</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- More options... -->
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cards (visual designs)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="cards">
|
||||||
|
<div class="card" data-choice="design1" onclick="toggleSelect(this)">
|
||||||
|
<div class="card-image">
|
||||||
|
<!-- Put mockup content here -->
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h3>Design Name</h3>
|
||||||
|
<p>Brief description</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mockup Container
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="mockup">
|
||||||
|
<div class="mockup-header">Preview: Dashboard Layout</div>
|
||||||
|
<div class="mockup-body">
|
||||||
|
<!-- Your mockup HTML -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Split View (side-by-side)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="split">
|
||||||
|
<div class="mockup"><!-- Left side --></div>
|
||||||
|
<div class="mockup"><!-- Right side --></div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pros/Cons
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="pros-cons">
|
||||||
|
<div class="pros">
|
||||||
|
<h4>Pros</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Benefit one</li>
|
||||||
|
<li>Benefit two</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="cons">
|
||||||
|
<h4>Cons</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Drawback one</li>
|
||||||
|
<li>Drawback two</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inline Mockup Elements
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="mock-nav">Logo | Home | About | Contact</div>
|
||||||
|
<div style="display: flex;">
|
||||||
|
<div class="mock-sidebar">Navigation</div>
|
||||||
|
<div class="mock-content">Main content area</div>
|
||||||
|
</div>
|
||||||
|
<button class="mock-button">Action Button</button>
|
||||||
|
<input class="mock-input" placeholder="Input field">
|
||||||
|
```
|
||||||
|
|
||||||
|
## User Feedback
|
||||||
|
|
||||||
|
When the user clicks Send, you receive JSON like:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"choice": "a", "feedback": "I like this but make the header smaller"}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `choice` - which option/card they selected (from `data-choice` attribute)
|
||||||
|
- `feedback` - any notes they typed
|
||||||
|
|
||||||
|
## Example: Design Comparison
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div id="claude-content">
|
||||||
|
<h2>Which blog layout works better?</h2>
|
||||||
|
<p class="subtitle">Consider readability and visual hierarchy</p>
|
||||||
|
|
||||||
|
<div class="cards">
|
||||||
|
<div class="card" data-choice="classic" onclick="toggleSelect(this)">
|
||||||
|
<div class="card-image">
|
||||||
|
<div style="padding: 1rem;">
|
||||||
|
<div class="mock-nav">Blog Title</div>
|
||||||
|
<div style="padding: 1rem;">
|
||||||
|
<h3 style="margin-bottom: 0.5rem;">Post Title</h3>
|
||||||
|
<p style="color: var(--text-secondary); font-size: 0.9rem;">
|
||||||
|
Content preview text goes here...
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h3>Classic Layout</h3>
|
||||||
|
<p>Traditional blog with posts in a single column</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" data-choice="magazine" onclick="toggleSelect(this)">
|
||||||
|
<div class="card-image">
|
||||||
|
<div style="padding: 1rem;">
|
||||||
|
<div class="mock-nav">Blog Title</div>
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; padding: 0.5rem;">
|
||||||
|
<div class="placeholder" style="padding: 1rem;">Featured</div>
|
||||||
|
<div class="placeholder" style="padding: 0.5rem;">Post</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h3>Magazine Layout</h3>
|
||||||
|
<p>Grid-based with featured posts</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
1. **Keep mockups simple** - Focus on layout and structure, not pixel-perfect design
|
||||||
|
2. **Use placeholders** - The `.placeholder` class works great for content areas
|
||||||
|
3. **Label clearly** - Use `.mockup-header` to explain what each mockup shows
|
||||||
|
4. **Limit choices** - 2-4 options is ideal; more gets overwhelming
|
||||||
|
5. **Provide context** - Use `.subtitle` to explain what you're asking
|
||||||
|
6. **Regenerate fully** - Write the complete HTML each turn; don't try to patch
|
||||||
@@ -232,5 +232,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let selectedChoice = null;
|
||||||
|
|
||||||
|
function toggleSelect(el) {
|
||||||
|
const container = el.closest('.options') || el.closest('.cards');
|
||||||
|
if (container) {
|
||||||
|
container.querySelectorAll('.option, .card').forEach(o => o.classList.remove('selected'));
|
||||||
|
}
|
||||||
|
el.classList.add('selected');
|
||||||
|
selectedChoice = el.dataset.choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
function send() {
|
||||||
|
const feedbackEl = document.getElementById('feedback');
|
||||||
|
const feedback = feedbackEl.value.trim();
|
||||||
|
const payload = {};
|
||||||
|
if (selectedChoice) payload.choice = selectedChoice;
|
||||||
|
if (feedback) payload.feedback = feedback;
|
||||||
|
if (Object.keys(payload).length === 0) return;
|
||||||
|
brainstorm.sendToClaude(payload);
|
||||||
|
feedbackEl.value = '';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
ws = new WebSocket(WS_URL);
|
ws = new WebSocket(WS_URL);
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
|
// Send any queued events
|
||||||
eventQueue.forEach(e => ws.send(JSON.stringify(e)));
|
eventQueue.forEach(e => ws.send(JSON.stringify(e)));
|
||||||
eventQueue = [];
|
eventQueue = [];
|
||||||
};
|
};
|
||||||
@@ -19,11 +20,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
|
// Reconnect after 1 second
|
||||||
setTimeout(connect, 1000);
|
setTimeout(connect, 1000);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendEvent(event) {
|
function send(event) {
|
||||||
event.timestamp = Date.now();
|
event.timestamp = Date.now();
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
ws.send(JSON.stringify(event));
|
ws.send(JSON.stringify(event));
|
||||||
@@ -40,12 +42,9 @@
|
|||||||
// Don't capture regular link navigation
|
// Don't capture regular link navigation
|
||||||
if (target.tagName === 'A' && !target.dataset.choice) return;
|
if (target.tagName === 'A' && !target.dataset.choice) return;
|
||||||
|
|
||||||
// Don't capture the Send feedback button (handled by send())
|
|
||||||
if (target.id === 'send-feedback') return;
|
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
sendEvent({
|
send({
|
||||||
type: 'click',
|
type: 'click',
|
||||||
text: target.textContent.trim(),
|
text: target.textContent.trim(),
|
||||||
choice: target.dataset.choice || null,
|
choice: target.dataset.choice || null,
|
||||||
@@ -62,7 +61,7 @@
|
|||||||
const data = {};
|
const data = {};
|
||||||
formData.forEach((value, key) => { data[key] = value; });
|
formData.forEach((value, key) => { data[key] = value; });
|
||||||
|
|
||||||
sendEvent({
|
send({
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
formId: form.id || null,
|
formId: form.id || null,
|
||||||
formName: form.name || null,
|
formName: form.name || null,
|
||||||
@@ -78,60 +77,37 @@
|
|||||||
|
|
||||||
clearTimeout(inputTimeout);
|
clearTimeout(inputTimeout);
|
||||||
inputTimeout = setTimeout(() => {
|
inputTimeout = setTimeout(() => {
|
||||||
sendEvent({
|
send({
|
||||||
type: 'input',
|
type: 'input',
|
||||||
name: target.name || null,
|
name: target.name || null,
|
||||||
id: target.id || null,
|
id: target.id || null,
|
||||||
value: target.value,
|
value: target.value,
|
||||||
inputType: target.type || target.tagName.toLowerCase()
|
inputType: target.type || target.tagName.toLowerCase()
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500); // 500ms debounce
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send to Claude - triggers feedback delivery
|
// Send to Claude - triggers server to exit and return all events
|
||||||
function sendToClaude(feedback) {
|
function sendToClaude(feedback) {
|
||||||
sendEvent({
|
send({
|
||||||
type: 'send-to-claude',
|
type: 'send-to-claude',
|
||||||
feedback: feedback || null
|
feedback: feedback || null
|
||||||
});
|
});
|
||||||
// Show themed confirmation page
|
// Show confirmation to user
|
||||||
document.body.innerHTML = `
|
document.body.innerHTML = `
|
||||||
<div style="display: flex; align-items: center; justify-content: center; height: 100vh; font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif; background: var(--bg-primary, #f5f5f7);">
|
<div style="display: flex; align-items: center; justify-content: center; height: 100vh; font-family: system-ui, sans-serif;">
|
||||||
<div style="text-align: center; color: var(--text-secondary, #86868b);">
|
<div style="text-align: center; color: #666;">
|
||||||
<h2 style="color: var(--text-primary, #1d1d1f); margin-bottom: 0.5rem;">Sent to Claude</h2>
|
<h2 style="color: #333;">✓ Sent to Claude</h2>
|
||||||
<p>Return to the terminal to see Claude's response.</p>
|
<p>Return to the terminal to see Claude's response.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame UI: selection tracking and feedback send
|
// Expose for explicit use if needed
|
||||||
window.selectedChoice = null;
|
|
||||||
|
|
||||||
window.toggleSelect = function(el) {
|
|
||||||
const container = el.closest('.options') || el.closest('.cards');
|
|
||||||
if (container) {
|
|
||||||
container.querySelectorAll('.option, .card').forEach(o => o.classList.remove('selected'));
|
|
||||||
}
|
|
||||||
el.classList.add('selected');
|
|
||||||
window.selectedChoice = el.dataset.choice;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.send = function() {
|
|
||||||
const feedbackEl = document.getElementById('feedback');
|
|
||||||
const feedback = feedbackEl ? feedbackEl.value.trim() : '';
|
|
||||||
const payload = {};
|
|
||||||
if (window.selectedChoice) payload.choice = window.selectedChoice;
|
|
||||||
if (feedback) payload.feedback = feedback;
|
|
||||||
if (Object.keys(payload).length === 0) return;
|
|
||||||
sendToClaude(payload);
|
|
||||||
if (feedbackEl) feedbackEl.value = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expose API for explicit use
|
|
||||||
window.brainstorm = {
|
window.brainstorm = {
|
||||||
send: sendEvent,
|
send: send,
|
||||||
choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata }),
|
choice: (value, metadata = {}) => send({ type: 'choice', value, ...metadata }),
|
||||||
sendToClaude: sendToClaude
|
sendToClaude: sendToClaude
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,32 +5,15 @@ const chokidar = require('chokidar');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
|
// Use provided port or pick a random high port (49152-65535)
|
||||||
const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() * 16383));
|
const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() * 16383));
|
||||||
const SCREEN_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm';
|
const SCREEN_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm';
|
||||||
|
|
||||||
|
// Ensure screen directory exists
|
||||||
if (!fs.existsSync(SCREEN_DIR)) {
|
if (!fs.existsSync(SCREEN_DIR)) {
|
||||||
fs.mkdirSync(SCREEN_DIR, { recursive: true });
|
fs.mkdirSync(SCREEN_DIR, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load frame template and helper script once at startup
|
|
||||||
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 = `<script>\n${helperScript}\n</script>`;
|
|
||||||
|
|
||||||
// Detect whether content is a full HTML document or a bare fragment
|
|
||||||
function isFullDocument(html) {
|
|
||||||
const trimmed = html.trimStart().toLowerCase();
|
|
||||||
return trimmed.startsWith('<!doctype') || trimmed.startsWith('<html');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap a content fragment in the frame template
|
|
||||||
function wrapInFrame(content) {
|
|
||||||
return frameTemplate.replace(
|
|
||||||
/(<div id="claude-content">)[\s\S]*?(<\/div>\s*<\/div>\s*<div class="feedback-footer">)/,
|
|
||||||
`$1\n ${content}\n $2`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the newest .html file in the directory by mtime
|
// Find the newest .html file in the directory by mtime
|
||||||
function getNewestScreen() {
|
function getNewestScreen() {
|
||||||
const files = fs.readdirSync(SCREEN_DIR)
|
const files = fs.readdirSync(SCREEN_DIR)
|
||||||
@@ -45,6 +28,7 @@ function getNewestScreen() {
|
|||||||
return files.length > 0 ? files[0].path : null;
|
return files.length > 0 ? files[0].path : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default waiting page (served when no screens exist yet)
|
||||||
const WAITING_PAGE = `<!DOCTYPE html>
|
const WAITING_PAGE = `<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -65,6 +49,7 @@ const app = express();
|
|||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
const wss = new WebSocket.Server({ server });
|
const wss = new WebSocket.Server({ server });
|
||||||
|
|
||||||
|
// Track connected browsers for reload notifications
|
||||||
const clients = new Set();
|
const clients = new Set();
|
||||||
|
|
||||||
wss.on('connection', (ws) => {
|
wss.on('connection', (ws) => {
|
||||||
@@ -72,6 +57,7 @@ wss.on('connection', (ws) => {
|
|||||||
ws.on('close', () => clients.delete(ws));
|
ws.on('close', () => clients.delete(ws));
|
||||||
|
|
||||||
ws.on('message', (data) => {
|
ws.on('message', (data) => {
|
||||||
|
// User interaction event - write to stdout for Claude
|
||||||
const event = JSON.parse(data.toString());
|
const event = JSON.parse(data.toString());
|
||||||
console.log(JSON.stringify({ source: 'user-event', ...event }));
|
console.log(JSON.stringify({ source: 'user-event', ...event }));
|
||||||
});
|
});
|
||||||
@@ -80,30 +66,27 @@ wss.on('connection', (ws) => {
|
|||||||
// Serve newest screen with helper.js injected
|
// Serve newest screen with helper.js injected
|
||||||
app.get('/', (req, res) => {
|
app.get('/', (req, res) => {
|
||||||
const screenFile = getNewestScreen();
|
const screenFile = getNewestScreen();
|
||||||
let html;
|
let html = screenFile ? fs.readFileSync(screenFile, 'utf-8') : WAITING_PAGE;
|
||||||
|
|
||||||
if (!screenFile) {
|
// Inject helper script before </body>
|
||||||
html = WAITING_PAGE;
|
const helperScript = fs.readFileSync(path.join(__dirname, 'helper.js'), 'utf-8');
|
||||||
} else {
|
const injection = `<script>\n${helperScript}\n</script>`;
|
||||||
const raw = fs.readFileSync(screenFile, 'utf-8');
|
|
||||||
html = isFullDocument(raw) ? raw : wrapInFrame(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inject helper script
|
|
||||||
if (html.includes('</body>')) {
|
if (html.includes('</body>')) {
|
||||||
html = html.replace('</body>', `${helperInjection}\n</body>`);
|
html = html.replace('</body>', `${injection}\n</body>`);
|
||||||
} else {
|
} else {
|
||||||
html += helperInjection;
|
html += injection;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.type('html').send(html);
|
res.type('html').send(html);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watch for new or changed .html files
|
// Watch for new or changed .html files in the directory
|
||||||
chokidar.watch(SCREEN_DIR, { ignoreInitial: true })
|
chokidar.watch(SCREEN_DIR, { ignoreInitial: true })
|
||||||
.on('add', (filePath) => {
|
.on('add', (filePath) => {
|
||||||
if (filePath.endsWith('.html')) {
|
if (filePath.endsWith('.html')) {
|
||||||
console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
|
console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
|
||||||
|
// Notify all browsers to reload
|
||||||
clients.forEach(ws => {
|
clients.forEach(ws => {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
ws.send(JSON.stringify({ type: 'reload' }));
|
ws.send(JSON.stringify({ type: 'reload' }));
|
||||||
|
|||||||
@@ -1,40 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Start the brainstorm server and output connection info
|
# Start the brainstorm server and output connection info
|
||||||
# Usage: start-server.sh [--project-dir <path>]
|
# Usage: start-server.sh
|
||||||
#
|
#
|
||||||
# Starts server on a random high port, outputs JSON with URL.
|
# Starts server on a random high port, outputs JSON with URL
|
||||||
# Each session gets its own directory to avoid conflicts.
|
# Each session gets its own temp directory to avoid conflicts
|
||||||
#
|
# Server runs in background, PID saved for cleanup
|
||||||
# Options:
|
|
||||||
# --project-dir <path> Store session files under <path>/.superpowers/brainstorm/
|
|
||||||
# instead of /tmp. Files persist after server stops.
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
# Parse arguments
|
|
||||||
PROJECT_DIR=""
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--project-dir)
|
|
||||||
PROJECT_DIR="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "{\"error\": \"Unknown argument: $1\"}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Generate unique session directory
|
# Generate unique session directory
|
||||||
SESSION_ID="$$-$(date +%s)"
|
SESSION_ID="$$-$(date +%s)"
|
||||||
|
SCREEN_DIR="/tmp/brainstorm-${SESSION_ID}"
|
||||||
if [[ -n "$PROJECT_DIR" ]]; then
|
|
||||||
SCREEN_DIR="${PROJECT_DIR}/.superpowers/brainstorm/${SESSION_ID}"
|
|
||||||
else
|
|
||||||
SCREEN_DIR="/tmp/brainstorm-${SESSION_ID}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PID_FILE="${SCREEN_DIR}/.server.pid"
|
PID_FILE="${SCREEN_DIR}/.server.pid"
|
||||||
LOG_FILE="${SCREEN_DIR}/.server.log"
|
LOG_FILE="${SCREEN_DIR}/.server.log"
|
||||||
|
|
||||||
@@ -57,6 +33,7 @@ echo "$SERVER_PID" > "$PID_FILE"
|
|||||||
# Wait for server-started message (check log file)
|
# Wait for server-started message (check log file)
|
||||||
for i in {1..50}; do
|
for i in {1..50}; do
|
||||||
if grep -q "server-started" "$LOG_FILE" 2>/dev/null; then
|
if grep -q "server-started" "$LOG_FILE" 2>/dev/null; then
|
||||||
|
# Extract and output the server-started line
|
||||||
grep "server-started" "$LOG_FILE" | head -1
|
grep "server-started" "$LOG_FILE" | head -1
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Stop the brainstorm server and clean up
|
# Stop the brainstorm server and clean up session directory
|
||||||
# Usage: stop-server.sh <screen_dir>
|
# Usage: stop-server.sh <screen_dir>
|
||||||
#
|
|
||||||
# Kills the server process. Only deletes session directory if it's
|
|
||||||
# under /tmp (ephemeral). Persistent directories (.superpowers/) are
|
|
||||||
# kept so mockups can be reviewed later.
|
|
||||||
|
|
||||||
SCREEN_DIR="$1"
|
SCREEN_DIR="$1"
|
||||||
|
|
||||||
@@ -18,13 +14,8 @@ PID_FILE="${SCREEN_DIR}/.server.pid"
|
|||||||
if [[ -f "$PID_FILE" ]]; then
|
if [[ -f "$PID_FILE" ]]; then
|
||||||
pid=$(cat "$PID_FILE")
|
pid=$(cat "$PID_FILE")
|
||||||
kill "$pid" 2>/dev/null
|
kill "$pid" 2>/dev/null
|
||||||
rm -f "$PID_FILE" "${SCREEN_DIR}/.server.log"
|
# Clean up session directory
|
||||||
|
rm -rf "$SCREEN_DIR"
|
||||||
# Only delete ephemeral /tmp directories
|
|
||||||
if [[ "$SCREEN_DIR" == /tmp/* ]]; then
|
|
||||||
rm -rf "$SCREEN_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo '{"status": "stopped"}'
|
echo '{"status": "stopped"}'
|
||||||
else
|
else
|
||||||
echo '{"status": "not_running"}'
|
echo '{"status": "not_running"}'
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ description: "You MUST use this before any creative work - creating features, bu
|
|||||||
|
|
||||||
# Brainstorming Ideas Into Designs
|
# Brainstorming Ideas Into Designs
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
Help turn ideas into fully formed designs and specs through natural collaborative dialogue.
|
Help turn ideas into fully formed designs and specs through natural collaborative dialogue.
|
||||||
|
|
||||||
Start by understanding the current project context, then ask questions one at a time to refine the idea. Once you understand what you're building, present the design in small sections (200-300 words), checking after each section whether it looks right so far.
|
Start by understanding the current project context, then ask questions one at a time to refine the idea. Once you understand what you're building, present the design in small sections (200-300 words), checking after each section whether it looks right so far.
|
||||||
@@ -13,9 +15,7 @@ Start by understanding the current project context, then ask questions one at a
|
|||||||
|
|
||||||
**Understanding the idea:**
|
**Understanding the idea:**
|
||||||
- Check out the current project state first (files, docs, recent commits)
|
- Check out the current project state first (files, docs, recent commits)
|
||||||
- Before asking detailed questions, assess scope: if the request describes multiple independent subsystems (e.g., "build a platform with chat, file storage, billing, and analytics"), flag this immediately. Don't spend questions refining details of a project that needs to be decomposed first.
|
- Ask questions one at a time to refine the idea
|
||||||
- If the project is too large for a single spec, help the user decompose into sub-projects: what are the independent pieces, how do they relate, what order should they be built? Then brainstorm the first sub-project through the normal design flow. Each sub-project gets its own spec → plan → implementation cycle.
|
|
||||||
- For appropriately-scoped projects, ask questions one at a time to refine the idea
|
|
||||||
- Prefer multiple choice questions when possible, but open-ended is fine too
|
- Prefer multiple choice questions when possible, but open-ended is fine too
|
||||||
- Only one question per message - if a topic needs more exploration, break it into multiple questions
|
- Only one question per message - if a topic needs more exploration, break it into multiple questions
|
||||||
- Focus on understanding: purpose, constraints, success criteria
|
- Focus on understanding: purpose, constraints, success criteria
|
||||||
@@ -32,37 +32,17 @@ Start by understanding the current project context, then ask questions one at a
|
|||||||
- Cover: architecture, components, data flow, error handling, testing
|
- Cover: architecture, components, data flow, error handling, testing
|
||||||
- Be ready to go back and clarify if something doesn't make sense
|
- Be ready to go back and clarify if something doesn't make sense
|
||||||
|
|
||||||
**Design for isolation and clarity:**
|
|
||||||
- Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently
|
|
||||||
- For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on?
|
|
||||||
- Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work.
|
|
||||||
- Smaller, well-bounded units are also easier for you to work with - you reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that's often a signal that it's doing too much.
|
|
||||||
|
|
||||||
**Working in existing codebases:**
|
|
||||||
- Explore the current structure before proposing changes. Follow existing patterns.
|
|
||||||
- Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design - the way a good developer improves code they're working in.
|
|
||||||
- Don't propose unrelated refactoring. Stay focused on what serves the current goal.
|
|
||||||
|
|
||||||
## After the Design
|
## After the Design
|
||||||
|
|
||||||
**Documentation:**
|
**Documentation:**
|
||||||
- Write the validated design (spec) to `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md`
|
- Write the validated design to `docs/plans/YYYY-MM-DD-<topic>-design.md`
|
||||||
- (User preferences for spec location override this default)
|
|
||||||
- Use elements-of-style:writing-clearly-and-concisely skill if available
|
- Use elements-of-style:writing-clearly-and-concisely skill if available
|
||||||
- Commit the design document to git
|
- Commit the design document to git
|
||||||
|
|
||||||
**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, re-dispatch, repeat until Approved
|
|
||||||
3. If loop exceeds 5 iterations, surface to human for guidance
|
|
||||||
|
|
||||||
**Implementation (if continuing):**
|
**Implementation (if continuing):**
|
||||||
- Ask: "Ready to set up for implementation?"
|
- Ask: "Ready to set up for implementation?"
|
||||||
- Use superpowers:using-git-worktrees to create isolated workspace
|
- Use superpowers:using-git-worktrees to create isolated workspace
|
||||||
- **REQUIRED:** Use superpowers:writing-plans to create detailed implementation plan
|
- Use superpowers:writing-plans to create detailed implementation plan
|
||||||
- Do NOT use platform planning features (e.g., EnterPlanMode, plan mode)
|
|
||||||
- Do NOT start implementing directly - the writing-plans skill comes first
|
|
||||||
|
|
||||||
## Key Principles
|
## Key Principles
|
||||||
|
|
||||||
@@ -75,10 +55,83 @@ After writing the spec document:
|
|||||||
|
|
||||||
## Visual Companion (Claude Code Only)
|
## Visual Companion (Claude Code Only)
|
||||||
|
|
||||||
A browser-based visual companion for showing mockups, diagrams, and options during brainstorming. Use it whenever visual representation would make feedback easier than text descriptions alone.
|
A browser-based visual companion for showing mockups, diagrams, and options. Use it whenever visual representation makes feedback easier. **Only works in Claude Code.**
|
||||||
|
|
||||||
**When the topic involves visual decisions, ask:**
|
### When to Use
|
||||||
> "This involves some visual decisions. I can show mockups in a browser window so you can see options and give feedback visually. This feature is still new — it can be token-intensive and a bit slow, but it works well for layout, design, and architecture questions. Want to try it? (Requires opening a local URL)"
|
|
||||||
|
|
||||||
If they agree, read the detailed guide before proceeding:
|
Use the visual companion when seeing beats describing:
|
||||||
`${CLAUDE_PLUGIN_ROOT}/skills/brainstorming/visual-companion.md`
|
- **UI mockups** - layouts, navigation, component designs
|
||||||
|
- **Architecture diagrams** - system components, data flow, relationships
|
||||||
|
- **Complex choices** - multi-option decisions with visual trade-offs
|
||||||
|
- **Design polish** - when the question is about look and feel
|
||||||
|
- **Spatial relationships** - file structures, database schemas, state machines
|
||||||
|
|
||||||
|
**Always ask first:**
|
||||||
|
> "This involves some visual decisions. Would you like me to show mockups in a browser window? (Requires opening a local URL)"
|
||||||
|
|
||||||
|
Only proceed if they agree. Otherwise, describe options in text.
|
||||||
|
|
||||||
|
### How to Use Effectively
|
||||||
|
|
||||||
|
**Scale fidelity to the question.** If you're asking about layout structure, simple wireframes suffice. If you're asking about visual polish, show polish. Match the mockup's detail level to what you're trying to learn.
|
||||||
|
|
||||||
|
**Explain the question on each page.** Don't just show options—state what decision you're seeking. "Which layout feels more professional?" not just "Pick one."
|
||||||
|
|
||||||
|
**Iterate before moving on.** If feedback changes the current screen, update it and show again. Validate that your changes address their feedback before proceeding to the next question.
|
||||||
|
|
||||||
|
**Limit choices to 2-4 options.** More gets overwhelming. If you have more alternatives, narrow them down first or group them.
|
||||||
|
|
||||||
|
**Use real content when it matters.** For a photography portfolio, use actual images (Unsplash). For a blog, use realistic text. Placeholder content obscures design issues.
|
||||||
|
|
||||||
|
### Starting a Session
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start server (creates unique session directory)
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
|
||||||
|
|
||||||
|
# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
|
||||||
|
# "screen_dir":"/tmp/brainstorm-12345"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Save `screen_dir` from the response. Tell user to open the URL.
|
||||||
|
|
||||||
|
### The Loop
|
||||||
|
|
||||||
|
1. **Start watcher first** (background bash) - avoids race condition:
|
||||||
|
```bash
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-feedback.sh $SCREEN_DIR
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Write HTML** to a new file in `screen_dir`:
|
||||||
|
- Use semantic filenames: `platform.html`, `visual-style.html`, `layout.html`
|
||||||
|
- **Never reuse filenames** - each screen gets a fresh file
|
||||||
|
- Use Write tool - **never use cat/heredoc** (dumps noise into terminal)
|
||||||
|
- Server automatically serves the newest file
|
||||||
|
|
||||||
|
3. **Tell user what to expect:**
|
||||||
|
- Remind them of the URL (every step, not just first)
|
||||||
|
- Give a brief text summary of what's on screen (e.g., "Showing 3 layout options for the homepage")
|
||||||
|
- This lets them know what to look for before switching to browser
|
||||||
|
|
||||||
|
4. **Wait for feedback** - call `TaskOutput(task_id, block=true, timeout=600000)`
|
||||||
|
- If timeout, call TaskOutput again (watcher still running)
|
||||||
|
- After 3 timeouts (30 min), say "Let me know when you want to continue"
|
||||||
|
|
||||||
|
5. **Process feedback** - returns JSON like `{"choice": "a", "feedback": "make header smaller"}`
|
||||||
|
|
||||||
|
6. **Iterate or advance** - if feedback changes current screen, write a new file (e.g., `layout-v2.html`). Only move to next question when current step is validated.
|
||||||
|
|
||||||
|
7. Repeat until done.
|
||||||
|
|
||||||
|
### Cleaning Up
|
||||||
|
|
||||||
|
```bash
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resources
|
||||||
|
|
||||||
|
- Frame template: `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/frame-template.html`
|
||||||
|
- CSS classes: `.options`, `.cards`, `.mockup`, `.split`, `.pros-cons`
|
||||||
|
- Detailed examples: `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md`
|
||||||
|
- Quick reference: `${CLAUDE_PLUGIN_ROOT}/skills/brainstorming/visual-companion.md`
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
# 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 |
|
|
||||||
| Scope | Focused enough for a single plan — not covering multiple independent subsystems |
|
|
||||||
| Architecture | Units with clear boundaries, well-defined interfaces, independently understandable and testable |
|
|
||||||
|
|
||||||
## 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
|
|
||||||
- Units that lack clear boundaries or interfaces — can you understand what each unit does without reading its internals?
|
|
||||||
|
|
||||||
## 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
|
|
||||||
@@ -1,97 +1,62 @@
|
|||||||
# Visual Companion Guide
|
# Visual Companion Reference
|
||||||
|
|
||||||
Browser-based visual brainstorming companion for showing mockups, diagrams, and options.
|
Quick reference for the browser-based visual brainstorming companion.
|
||||||
|
|
||||||
## When to Use
|
## Files
|
||||||
|
|
||||||
Use the visual companion when seeing beats describing:
|
| File | Purpose |
|
||||||
- **UI mockups** — layouts, navigation, component designs
|
|------|---------|
|
||||||
- **Architecture diagrams** — system components, data flow, relationships
|
| `lib/brainstorm-server/start-server.sh` | Start server, outputs JSON with URL and session paths |
|
||||||
- **Complex choices** — multi-option decisions with visual trade-offs
|
| `lib/brainstorm-server/stop-server.sh` | Stop server and clean up session directory |
|
||||||
- **Design polish** — when the question is about look and feel
|
| `lib/brainstorm-server/wait-for-feedback.sh` | Wait for user feedback (polling-based) |
|
||||||
- **Spatial relationships** — file structures, database schemas, state machines
|
| `lib/brainstorm-server/frame-template.html` | Base HTML template with CSS |
|
||||||
|
| `lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md` | Detailed usage guide |
|
||||||
|
|
||||||
Don't use it for simple text questions, code review, or when the user prefers terminal-only interaction.
|
## Quick Start
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
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, clicks options or types feedback, and you receive their response as JSON.
|
|
||||||
|
|
||||||
**Content fragments vs full documents:** If your HTML file starts with `<!DOCTYPE` or `<html`, the server serves it as-is (just injects the helper script). Otherwise, the server automatically wraps your content in the frame template — adding the header, CSS theme, feedback footer, and all interactive infrastructure. **Write content fragments by default.** Only write full documents when you need complete control over the page.
|
|
||||||
|
|
||||||
## Starting a Session
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Start server with persistence (mockups saved to project)
|
# 1. Start server
|
||||||
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh --project-dir /path/to/project
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
|
||||||
|
# Returns: {"screen_dir":"/tmp/brainstorm-xxx","url":"http://localhost:PORT"}
|
||||||
|
|
||||||
# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
|
# 2. Start watcher FIRST (background bash) - avoids race condition
|
||||||
# "screen_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000"}
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-feedback.sh $SCREEN_DIR
|
||||||
|
|
||||||
|
# 3. Write HTML to a NEW file in screen_dir (e.g., platform.html, style.html)
|
||||||
|
# Never reuse filenames - server serves newest file automatically
|
||||||
|
|
||||||
|
# 4. Call TaskOutput(task_id, block=true, timeout=600000)
|
||||||
|
# If timeout, call again. After 3 timeouts (30 min), prompt user.
|
||||||
|
# Returns: {"choice":"a","feedback":"user notes"}
|
||||||
|
|
||||||
|
# 5. Iterate or advance - write new file if feedback changes it (e.g., style-v2.html)
|
||||||
|
|
||||||
|
# 6. Clean up when done
|
||||||
|
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
|
||||||
```
|
```
|
||||||
|
|
||||||
Save `screen_dir` from the response. Tell user to open the URL.
|
## Key Principles
|
||||||
|
|
||||||
**Note:** Pass the project root as `--project-dir` so mockups persist in `.superpowers/brainstorm/` and survive server restarts. Without it, files go to `/tmp` and get cleaned up. Remind the user to add `.superpowers/` to `.gitignore` if it's not already there.
|
- **Always ask first** before starting visual companion
|
||||||
|
- **Scale fidelity to the question** - wireframes for layout, polish for polish questions
|
||||||
|
- **Explain the question** on each page - what decision are you seeking?
|
||||||
|
- **Iterate before advancing** - if feedback changes current screen, write new version
|
||||||
|
- **2-4 options max** per screen
|
||||||
|
|
||||||
## The Loop
|
## File Naming
|
||||||
|
|
||||||
1. **Start watcher first** (background bash) — avoids race condition:
|
- **Use semantic names**: `platform.html`, `visual-style.html`, `layout.html`, `controls.html`
|
||||||
```bash
|
- **Never reuse filenames** - each screen is a new file
|
||||||
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-feedback.sh $SCREEN_DIR
|
- **For iterations**: append version suffix like `layout-v2.html`, `layout-v3.html`
|
||||||
```
|
- Server automatically serves the newest file by modification time
|
||||||
|
|
||||||
2. **Write HTML** to a new file in `screen_dir`:
|
## Terminal UX
|
||||||
- Use semantic filenames: `platform.html`, `visual-style.html`, `layout.html`
|
|
||||||
- **Never reuse filenames** — each screen gets a fresh file
|
|
||||||
- Use Write tool — **never use cat/heredoc** (dumps noise into terminal)
|
|
||||||
- Server automatically serves the newest file
|
|
||||||
|
|
||||||
3. **Tell user what to expect:**
|
- **Never use cat/heredoc for HTML** - dumps noise into terminal. Use Write tool instead.
|
||||||
- Remind them of the URL (every step, not just first)
|
- **Remind user of URL** on every step, not just the first
|
||||||
- Give a brief text summary of what's on screen (e.g., "Showing 3 layout options for the homepage")
|
- **Give text summary** of what's on screen before they look (e.g., "Showing 3 API structure options")
|
||||||
|
|
||||||
4. **Wait for feedback** — call `TaskOutput(task_id, block=true, timeout=600000)`
|
## CSS Classes
|
||||||
- If timeout, call TaskOutput again (watcher still running)
|
|
||||||
- After 3 timeouts (30 min), say "Let me know when you want to continue"
|
|
||||||
|
|
||||||
5. **Process feedback** — returns JSON like `{"choice": "a", "feedback": "make header smaller"}`
|
|
||||||
|
|
||||||
6. **Iterate or advance** — if feedback changes current screen, write a new file (e.g., `layout-v2.html`). Only move to the next question when the current step is validated.
|
|
||||||
|
|
||||||
7. Repeat until done.
|
|
||||||
|
|
||||||
## Writing Content Fragments
|
|
||||||
|
|
||||||
Write just the content that goes inside the page. The server wraps it in the frame template automatically (header, theme CSS, feedback footer, interactive JS).
|
|
||||||
|
|
||||||
**Minimal example:**
|
|
||||||
```html
|
|
||||||
<h2>Which layout works better?</h2>
|
|
||||||
<p class="subtitle">Consider readability and visual hierarchy</p>
|
|
||||||
|
|
||||||
<div class="options">
|
|
||||||
<div class="option" data-choice="a" onclick="toggleSelect(this)">
|
|
||||||
<div class="letter">A</div>
|
|
||||||
<div class="content">
|
|
||||||
<h3>Single Column</h3>
|
|
||||||
<p>Clean, focused reading experience</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="option" data-choice="b" onclick="toggleSelect(this)">
|
|
||||||
<div class="letter">B</div>
|
|
||||||
<div class="content">
|
|
||||||
<h3>Two Column</h3>
|
|
||||||
<p>Sidebar navigation with main content</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
That's it. No `<html>`, no CSS, no `<script>` tags needed. The server provides all of that.
|
|
||||||
|
|
||||||
## CSS Classes Available
|
|
||||||
|
|
||||||
The frame template provides these CSS classes for your content:
|
|
||||||
|
|
||||||
### Options (A/B/C choices)
|
### Options (A/B/C choices)
|
||||||
```html
|
```html
|
||||||
@@ -109,8 +74,8 @@ The frame template provides these CSS classes for your content:
|
|||||||
### Cards (visual designs)
|
### Cards (visual designs)
|
||||||
```html
|
```html
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
<div class="card" data-choice="design1" onclick="toggleSelect(this)">
|
<div class="card" data-choice="x" onclick="toggleSelect(this)">
|
||||||
<div class="card-image"><!-- mockup content --></div>
|
<div class="card-image"><!-- mockup --></div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3>Name</h3>
|
<h3>Name</h3>
|
||||||
<p>Description</p>
|
<p>Description</p>
|
||||||
@@ -122,82 +87,44 @@ The frame template provides these CSS classes for your content:
|
|||||||
### Mockup container
|
### Mockup container
|
||||||
```html
|
```html
|
||||||
<div class="mockup">
|
<div class="mockup">
|
||||||
<div class="mockup-header">Preview: Dashboard Layout</div>
|
<div class="mockup-header">Label</div>
|
||||||
<div class="mockup-body"><!-- your mockup HTML --></div>
|
<div class="mockup-body"><!-- content --></div>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Split view (side-by-side)
|
### Split view
|
||||||
```html
|
```html
|
||||||
<div class="split">
|
<div class="split">
|
||||||
<div class="mockup"><!-- left --></div>
|
<div><!-- left --></div>
|
||||||
<div class="mockup"><!-- right --></div>
|
<div><!-- right --></div>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Pros/Cons
|
### Pros/Cons
|
||||||
```html
|
```html
|
||||||
<div class="pros-cons">
|
<div class="pros-cons">
|
||||||
<div class="pros"><h4>Pros</h4><ul><li>Benefit</li></ul></div>
|
<div class="pros"><h4>Pros</h4><ul><li>...</li></ul></div>
|
||||||
<div class="cons"><h4>Cons</h4><ul><li>Drawback</li></ul></div>
|
<div class="cons"><h4>Cons</h4><ul><li>...</li></ul></div>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mock elements (wireframe building blocks)
|
### Mock elements
|
||||||
```html
|
```html
|
||||||
<div class="mock-nav">Logo | Home | About | Contact</div>
|
<div class="mock-nav">Nav items</div>
|
||||||
<div style="display: flex;">
|
<div class="mock-sidebar">Sidebar</div>
|
||||||
<div class="mock-sidebar">Navigation</div>
|
<div class="mock-content">Content</div>
|
||||||
<div class="mock-content">Main content area</div>
|
<button class="mock-button">Button</button>
|
||||||
</div>
|
<input class="mock-input" placeholder="Input">
|
||||||
<button class="mock-button">Action Button</button>
|
|
||||||
<input class="mock-input" placeholder="Input field">
|
|
||||||
<div class="placeholder">Placeholder area</div>
|
<div class="placeholder">Placeholder area</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Typography and sections
|
|
||||||
- `h2` — page title
|
|
||||||
- `h3` — section heading
|
|
||||||
- `.subtitle` — secondary text below title
|
|
||||||
- `.section` — content block with bottom margin
|
|
||||||
- `.label` — small uppercase label text
|
|
||||||
|
|
||||||
## User Feedback Format
|
## User Feedback Format
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"choice": "option-id",
|
"choice": "option-id", // from data-choice attribute
|
||||||
"feedback": "user notes"
|
"feedback": "user notes" // from feedback textarea
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Both fields are optional — user may select without notes, or send notes without a selection.
|
Both fields are optional - user may select without notes, or send notes without selection.
|
||||||
|
|
||||||
## Design Tips
|
|
||||||
|
|
||||||
- **Scale fidelity to the question** — wireframes for layout, polish for polish questions
|
|
||||||
- **Explain the question on each page** — "Which layout feels more professional?" not just "Pick one"
|
|
||||||
- **Iterate before advancing** — if feedback changes current screen, write a new version
|
|
||||||
- **2-4 options max** per screen
|
|
||||||
- **Use real content when it matters** — for a photography portfolio, use actual images (Unsplash). Placeholder content obscures design issues.
|
|
||||||
- **Keep mockups simple** — focus on layout and structure, not pixel-perfect design
|
|
||||||
|
|
||||||
## File Naming
|
|
||||||
|
|
||||||
- Use semantic names: `platform.html`, `visual-style.html`, `layout.html`
|
|
||||||
- Never reuse filenames — each screen must be a new file
|
|
||||||
- For iterations: append version suffix like `layout-v2.html`, `layout-v3.html`
|
|
||||||
- Server serves newest file by modification time
|
|
||||||
|
|
||||||
## Cleaning Up
|
|
||||||
|
|
||||||
```bash
|
|
||||||
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
|
|
||||||
```
|
|
||||||
|
|
||||||
If the session used `--project-dir`, mockup files persist in `.superpowers/brainstorm/` for later reference. Only `/tmp` sessions get deleted on stop.
|
|
||||||
|
|
||||||
## Reference
|
|
||||||
|
|
||||||
- Frame template (CSS reference): `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/frame-template.html`
|
|
||||||
- Helper script (JS API): `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/helper.js`
|
|
||||||
|
|||||||
@@ -74,11 +74,3 @@ After all tasks complete and verified:
|
|||||||
- Reference skills when plan says to
|
- Reference skills when plan says to
|
||||||
- Between batches: just report and wait
|
- Between batches: just report and wait
|
||||||
- Stop when blocked, don't guess
|
- 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
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ HEAD_SHA=$(git rev-parse HEAD)
|
|||||||
|
|
||||||
[Dispatch superpowers:code-reviewer subagent]
|
[Dispatch superpowers:code-reviewer subagent]
|
||||||
WHAT_WAS_IMPLEMENTED: Verification and repair functions for conversation index
|
WHAT_WAS_IMPLEMENTED: Verification and repair functions for conversation index
|
||||||
PLAN_OR_REQUIREMENTS: Task 2 from docs/superpowers/plans/deployment-plan.md
|
PLAN_OR_REQUIREMENTS: Task 2 from docs/plans/deployment-plan.md
|
||||||
BASE_SHA: a7981ec
|
BASE_SHA: a7981ec
|
||||||
HEAD_SHA: 3df7661
|
HEAD_SHA: 3df7661
|
||||||
DESCRIPTION: Added verifyIndex() and repairIndex() with 4 issue types
|
DESCRIPTION: Added verifyIndex() and repairIndex() with 4 issue types
|
||||||
|
|||||||
@@ -82,39 +82,6 @@ digraph process {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Model Selection
|
|
||||||
|
|
||||||
Use the least powerful model that can handle each role to conserve cost and increase speed.
|
|
||||||
|
|
||||||
**Mechanical implementation tasks** (isolated functions, clear specs, 1-2 files): use a fast, cheap model. Most implementation tasks are mechanical when the plan is well-specified.
|
|
||||||
|
|
||||||
**Integration and judgment tasks** (multi-file coordination, pattern matching, debugging): use a standard model.
|
|
||||||
|
|
||||||
**Architecture, design, and review tasks**: use the most capable available model.
|
|
||||||
|
|
||||||
**Task complexity signals:**
|
|
||||||
- Touches 1-2 files with a complete spec → cheap model
|
|
||||||
- Touches multiple files with integration concerns → standard model
|
|
||||||
- Requires design judgment or broad codebase understanding → most capable model
|
|
||||||
|
|
||||||
## Handling Implementer Status
|
|
||||||
|
|
||||||
Implementer subagents report one of four statuses. Handle each appropriately:
|
|
||||||
|
|
||||||
**DONE:** Proceed to spec compliance review.
|
|
||||||
|
|
||||||
**DONE_WITH_CONCERNS:** The implementer completed the work but flagged doubts. Read the concerns before proceeding. If the concerns are about correctness or scope, address them before review. If they're observations (e.g., "this file is getting large"), note them and proceed to review.
|
|
||||||
|
|
||||||
**NEEDS_CONTEXT:** The implementer needs information that wasn't provided. Provide the missing context and re-dispatch.
|
|
||||||
|
|
||||||
**BLOCKED:** The implementer cannot complete the task. Assess the blocker:
|
|
||||||
1. If it's a context problem, provide more context and re-dispatch with the same model
|
|
||||||
2. If the task requires more reasoning, re-dispatch with a more capable model
|
|
||||||
3. If the task is too large, break it into smaller pieces
|
|
||||||
4. If the plan itself is wrong, escalate to the human
|
|
||||||
|
|
||||||
**Never** ignore an escalation or force the same model to retry without changes. If the implementer said it's stuck, something needs to change.
|
|
||||||
|
|
||||||
## Prompt Templates
|
## Prompt Templates
|
||||||
|
|
||||||
- `./implementer-prompt.md` - Dispatch implementer subagent
|
- `./implementer-prompt.md` - Dispatch implementer subagent
|
||||||
@@ -126,7 +93,7 @@ Implementer subagents report one of four statuses. Handle each appropriately:
|
|||||||
```
|
```
|
||||||
You: I'm using Subagent-Driven Development to execute this plan.
|
You: I'm using Subagent-Driven Development to execute this plan.
|
||||||
|
|
||||||
[Read plan file once: docs/superpowers/plans/feature-plan.md]
|
[Read plan file once: docs/plans/feature-plan.md]
|
||||||
[Extract all 5 tasks with full text and context]
|
[Extract all 5 tasks with full text and context]
|
||||||
[Create TodoWrite with all tasks]
|
[Create TodoWrite with all tasks]
|
||||||
|
|
||||||
@@ -232,7 +199,6 @@ Done!
|
|||||||
## Red Flags
|
## Red Flags
|
||||||
|
|
||||||
**Never:**
|
**Never:**
|
||||||
- Start implementation on main/master branch without explicit user consent
|
|
||||||
- Skip reviews (spec compliance OR code quality)
|
- Skip reviews (spec compliance OR code quality)
|
||||||
- Proceed with unfixed issues
|
- Proceed with unfixed issues
|
||||||
- Dispatch multiple implementation subagents in parallel (conflicts)
|
- Dispatch multiple implementation subagents in parallel (conflicts)
|
||||||
@@ -263,7 +229,6 @@ Done!
|
|||||||
## Integration
|
## Integration
|
||||||
|
|
||||||
**Required workflow skills:**
|
**Required workflow skills:**
|
||||||
- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting
|
|
||||||
- **superpowers:writing-plans** - Creates the plan this skill executes
|
- **superpowers:writing-plans** - Creates the plan this skill executes
|
||||||
- **superpowers:requesting-code-review** - Code review template for reviewer subagents
|
- **superpowers:requesting-code-review** - Code review template for reviewer subagents
|
||||||
- **superpowers:finishing-a-development-branch** - Complete development after all tasks
|
- **superpowers:finishing-a-development-branch** - Complete development after all tasks
|
||||||
|
|||||||
@@ -17,10 +17,4 @@ Task tool (superpowers:code-reviewer):
|
|||||||
DESCRIPTION: [task summary]
|
DESCRIPTION: [task summary]
|
||||||
```
|
```
|
||||||
|
|
||||||
**In addition to standard code quality concerns, the reviewer should check:**
|
|
||||||
- Does each file have one clear responsibility with a well-defined interface?
|
|
||||||
- Are units decomposed so they can be understood and tested independently?
|
|
||||||
- Is the implementation following the file structure from the plan?
|
|
||||||
- Did this implementation create new files that are already large, or significantly grow existing files? (Don't flag pre-existing file sizes — focus on what this change contributed.)
|
|
||||||
|
|
||||||
**Code reviewer returns:** Strengths, Issues (Critical/Important/Minor), Assessment
|
**Code reviewer returns:** Strengths, Issues (Critical/Important/Minor), Assessment
|
||||||
|
|||||||
@@ -41,36 +41,6 @@ Task tool (general-purpose):
|
|||||||
**While you work:** If you encounter something unexpected or unclear, **ask questions**.
|
**While you work:** If you encounter something unexpected or unclear, **ask questions**.
|
||||||
It's always OK to pause and clarify. Don't guess or make assumptions.
|
It's always OK to pause and clarify. Don't guess or make assumptions.
|
||||||
|
|
||||||
## Code Organization
|
|
||||||
|
|
||||||
You reason best about code you can hold in context at once, and your edits are more
|
|
||||||
reliable when files are focused. Keep this in mind:
|
|
||||||
- Follow the file structure defined in the plan
|
|
||||||
- Each file should have one clear responsibility with a well-defined interface
|
|
||||||
- If a file you're creating is growing beyond the plan's intent, stop and report
|
|
||||||
it as DONE_WITH_CONCERNS — don't split files on your own without plan guidance
|
|
||||||
- If an existing file you're modifying is already large or tangled, work carefully
|
|
||||||
and note it as a concern in your report
|
|
||||||
- In existing codebases, follow established patterns. Improve code you're touching
|
|
||||||
the way a good developer would, but don't restructure things outside your task.
|
|
||||||
|
|
||||||
## When You're in Over Your Head
|
|
||||||
|
|
||||||
It is always OK to stop and say "this is too hard for me." Bad work is worse than
|
|
||||||
no work. You will not be penalized for escalating.
|
|
||||||
|
|
||||||
**STOP and escalate when:**
|
|
||||||
- The task requires architectural decisions with multiple valid approaches
|
|
||||||
- You need to understand code beyond what was provided and can't find clarity
|
|
||||||
- You feel uncertain about whether your approach is correct
|
|
||||||
- The task involves restructuring existing code in ways the plan didn't anticipate
|
|
||||||
- You've been reading file after file trying to understand the system without progress
|
|
||||||
|
|
||||||
**How to escalate:** Report back with status BLOCKED or NEEDS_CONTEXT. Describe
|
|
||||||
specifically what you're stuck on, what you've tried, and what kind of help you need.
|
|
||||||
The controller can provide more context, re-dispatch with a more capable model,
|
|
||||||
or break the task into smaller pieces.
|
|
||||||
|
|
||||||
## Before Reporting Back: Self-Review
|
## Before Reporting Back: Self-Review
|
||||||
|
|
||||||
Review your work with fresh eyes. Ask yourself:
|
Review your work with fresh eyes. Ask yourself:
|
||||||
@@ -100,14 +70,9 @@ Task tool (general-purpose):
|
|||||||
## Report Format
|
## Report Format
|
||||||
|
|
||||||
When done, report:
|
When done, report:
|
||||||
- **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
|
- What you implemented
|
||||||
- What you implemented (or what you attempted, if blocked)
|
|
||||||
- What you tested and test results
|
- What you tested and test results
|
||||||
- Files changed
|
- Files changed
|
||||||
- Self-review findings (if any)
|
- Self-review findings (if any)
|
||||||
- Any issues or concerns
|
- Any issues or concerns
|
||||||
|
|
||||||
Use DONE_WITH_CONCERNS if you completed the work but have doubts about correctness.
|
|
||||||
Use BLOCKED if you cannot complete the task. Use NEEDS_CONTEXT if you need
|
|
||||||
information that wasn't provided. Never silently produce work you're unsure about.
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -210,9 +210,8 @@ Ready to implement auth feature
|
|||||||
|
|
||||||
**Called by:**
|
**Called by:**
|
||||||
- **brainstorming** (Phase 4) - REQUIRED when design is approved and implementation follows
|
- **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
|
- Any skill needing isolated workspace
|
||||||
|
|
||||||
**Pairs with:**
|
**Pairs with:**
|
||||||
- **finishing-a-development-branch** - REQUIRED for cleanup after work complete
|
- **finishing-a-development-branch** - REQUIRED for cleanup after work complete
|
||||||
|
- **executing-plans** or **subagent-driven-development** - Work happens in this worktree
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ name: using-superpowers
|
|||||||
description: Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
|
description: Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
|
||||||
---
|
---
|
||||||
|
|
||||||
<SUBAGENT-STOP>
|
|
||||||
If you were dispatched as a subagent to execute a specific task, skip this skill.
|
|
||||||
</SUBAGENT-STOP>
|
|
||||||
|
|
||||||
<EXTREMELY-IMPORTANT>
|
<EXTREMELY-IMPORTANT>
|
||||||
If you think there is even a 1% chance a skill might apply to what you are doing, you ABSOLUTELY MUST invoke the skill.
|
If you think there is even a 1% chance a skill might apply to what you are doing, you ABSOLUTELY MUST invoke the skill.
|
||||||
|
|
||||||
@@ -31,10 +27,6 @@ If CLAUDE.md says "don't use TDD" and a skill says "always use TDD," follow CLAU
|
|||||||
|
|
||||||
**In other environments:** Check your platform's documentation for how skills are loaded.
|
**In other environments:** Check your platform's documentation for how skills are loaded.
|
||||||
|
|
||||||
## Platform Adaptation
|
|
||||||
|
|
||||||
Skills use Claude Code tool names. Non-CC platforms: see `references/codex-tools.md` for tool equivalents.
|
|
||||||
|
|
||||||
# Using Skills
|
# Using Skills
|
||||||
|
|
||||||
## The Rule
|
## The Rule
|
||||||
@@ -81,7 +73,6 @@ These thoughts mean STOP—you're rationalizing:
|
|||||||
| "I'll just do this one thing first" | Check BEFORE doing anything. |
|
| "I'll just do this one thing first" | Check BEFORE doing anything. |
|
||||||
| "This feels productive" | Undisciplined action wastes time. Skills prevent this. |
|
| "This feels productive" | Undisciplined action wastes time. Skills prevent this. |
|
||||||
| "I know what that means" | Knowing the concept ≠ using the skill. Invoke it. |
|
| "I know what that means" | Knowing the concept ≠ using the skill. Invoke it. |
|
||||||
| "Let me enter plan mode first" | If a skill handles planning (writing-plans, brainstorming), use the skill directly. EnterPlanMode is redundant — never layer it with a planning skill. |
|
|
||||||
|
|
||||||
## Skill Priority
|
## Skill Priority
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
# Codex Tool Mapping
|
|
||||||
|
|
||||||
Skills use Claude Code tool names. When you encounter these in a skill, use your platform equivalent:
|
|
||||||
|
|
||||||
| Skill references | Codex equivalent |
|
|
||||||
|-----------------|------------------|
|
|
||||||
| `Task` tool (dispatch subagent) | `spawn_agent` |
|
|
||||||
| Multiple `Task` calls (parallel) | Multiple `spawn_agent` calls |
|
|
||||||
| Task returns result | `wait` |
|
|
||||||
| Task completes automatically | `close_agent` to free slot |
|
|
||||||
| `TodoWrite` (task tracking) | `update_plan` |
|
|
||||||
| `Skill` tool (invoke a skill) | Skills load natively — just follow the instructions |
|
|
||||||
| `Read`, `Write`, `Edit` (files) | Use your native file tools |
|
|
||||||
| `Bash` (run commands) | Use your native shell tools |
|
|
||||||
|
|
||||||
## Subagent dispatch requires collab
|
|
||||||
|
|
||||||
Add to your Codex config (`~/.codex/config.toml`):
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[features]
|
|
||||||
collab = true
|
|
||||||
```
|
|
||||||
|
|
||||||
This enables `spawn_agent`, `wait`, and `close_agent` for skills like `dispatching-parallel-agents` and `subagent-driven-development`.
|
|
||||||
@@ -5,8 +5,6 @@ description: Use when you have a spec or requirements for a multi-step task, bef
|
|||||||
|
|
||||||
# Writing Plans
|
# Writing Plans
|
||||||
|
|
||||||
**IMPORTANT:** Invoke this skill directly — do NOT use EnterPlanMode or platform plan mode. This skill has its own workflow and approval checkpoint (execution handoff). Layering plan mode on top is redundant and restrictive.
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Write comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI. TDD. Frequent commits.
|
Write comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI. TDD. Frequent commits.
|
||||||
@@ -17,23 +15,7 @@ Assume they are a skilled developer, but know almost nothing about our toolset o
|
|||||||
|
|
||||||
**Context:** This should be run in a dedicated worktree (created by brainstorming skill).
|
**Context:** This should be run in a dedicated worktree (created by brainstorming skill).
|
||||||
|
|
||||||
**Save plans to:** `docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md`
|
**Save plans to:** `docs/plans/YYYY-MM-DD-<feature-name>.md`
|
||||||
- (User preferences for plan location override this default)
|
|
||||||
|
|
||||||
## Scope Check
|
|
||||||
|
|
||||||
If the spec covers multiple independent subsystems, it should have been broken into sub-project specs during brainstorming. If it wasn't, suggest breaking this into separate plans — one per subsystem. Each plan should produce working, testable software on its own.
|
|
||||||
|
|
||||||
## File Structure
|
|
||||||
|
|
||||||
Before defining tasks, map out which files will be created or modified and what each one is responsible for. This is where decomposition decisions get locked in.
|
|
||||||
|
|
||||||
- Design units with clear boundaries and well-defined interfaces. Each file should have one clear responsibility.
|
|
||||||
- You reason best about code you can hold in context at once, and your edits are more reliable when files are focused. Prefer smaller, focused files over large ones that do too much.
|
|
||||||
- Files that change together should live together. Split by responsibility, not by technical layer.
|
|
||||||
- In existing codebases, follow established patterns. If the codebase uses large files, don't unilaterally restructure - but if a file you're modifying has grown unwieldy, including a split in the plan is reasonable.
|
|
||||||
|
|
||||||
This structure informs the task decomposition. Each task should produce self-contained changes that make sense independently.
|
|
||||||
|
|
||||||
## Bite-Sized Task Granularity
|
## Bite-Sized Task Granularity
|
||||||
|
|
||||||
@@ -51,7 +33,7 @@ This structure informs the task decomposition. Each task should produce self-con
|
|||||||
```markdown
|
```markdown
|
||||||
# [Feature Name] Implementation Plan
|
# [Feature Name] Implementation Plan
|
||||||
|
|
||||||
> **For Claude:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
**Goal:** [One sentence describing what this builds]
|
**Goal:** [One sentence describing what this builds]
|
||||||
|
|
||||||
@@ -72,7 +54,7 @@ This structure informs the task decomposition. Each task should produce self-con
|
|||||||
- Modify: `exact/path/to/existing.py:123-145`
|
- Modify: `exact/path/to/existing.py:123-145`
|
||||||
- Test: `tests/exact/path/to/test.py`
|
- Test: `tests/exact/path/to/test.py`
|
||||||
|
|
||||||
- [ ] **Step 1: Write the failing test**
|
**Step 1: Write the failing test**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def test_specific_behavior():
|
def test_specific_behavior():
|
||||||
@@ -80,24 +62,24 @@ def test_specific_behavior():
|
|||||||
assert result == expected
|
assert result == expected
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: Run test to verify it fails**
|
**Step 2: Run test to verify it fails**
|
||||||
|
|
||||||
Run: `pytest tests/path/test.py::test_name -v`
|
Run: `pytest tests/path/test.py::test_name -v`
|
||||||
Expected: FAIL with "function not defined"
|
Expected: FAIL with "function not defined"
|
||||||
|
|
||||||
- [ ] **Step 3: Write minimal implementation**
|
**Step 3: Write minimal implementation**
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def function(input):
|
def function(input):
|
||||||
return expected
|
return expected
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: Run test to verify it passes**
|
**Step 4: Run test to verify it passes**
|
||||||
|
|
||||||
Run: `pytest tests/path/test.py::test_name -v`
|
Run: `pytest tests/path/test.py::test_name -v`
|
||||||
Expected: PASS
|
Expected: PASS
|
||||||
|
|
||||||
- [ ] **Step 5: Commit**
|
**Step 5: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add tests/path/test.py src/path/file.py
|
git add tests/path/test.py src/path/file.py
|
||||||
@@ -112,38 +94,23 @@ git commit -m "feat: add specific feature"
|
|||||||
- Reference relevant skills with @ syntax
|
- Reference relevant skills with @ syntax
|
||||||
- DRY, YAGNI, TDD, frequent commits
|
- DRY, YAGNI, TDD, frequent commits
|
||||||
|
|
||||||
## Plan Review Loop
|
|
||||||
|
|
||||||
After completing each chunk of the plan:
|
|
||||||
|
|
||||||
1. Dispatch plan-document-reviewer subagent (see plan-document-reviewer-prompt.md) 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: <name>` headings to delimit chunks. Each chunk should be ≤1000 lines and logically self-contained.
|
|
||||||
|
|
||||||
**Review loop guidance:**
|
|
||||||
- Same agent that wrote the plan 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
|
|
||||||
|
|
||||||
## Execution Handoff
|
## Execution Handoff
|
||||||
|
|
||||||
After saving the plan:
|
After saving the plan, offer execution choice:
|
||||||
|
|
||||||
**"Plan complete and saved to `docs/superpowers/plans/<filename>.md`. Ready to execute?"**
|
**"Plan complete and saved to `docs/plans/<filename>.md`. Two execution options:**
|
||||||
|
|
||||||
**Execution path depends on harness capabilities:**
|
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
|
||||||
|
|
||||||
**If harness has subagents (Claude Code, etc.):**
|
**2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints
|
||||||
- **REQUIRED:** Use superpowers:subagent-driven-development
|
|
||||||
- Do NOT offer a choice - subagent-driven is the standard approach
|
|
||||||
- Fresh subagent per task + two-stage review
|
|
||||||
|
|
||||||
**If harness does NOT have subagents:**
|
**Which approach?"**
|
||||||
- Execute plan in current session using superpowers:executing-plans
|
|
||||||
- Batch execution with checkpoints for review
|
**If Subagent-Driven chosen:**
|
||||||
|
- **REQUIRED SUB-SKILL:** Use superpowers:subagent-driven-development
|
||||||
|
- Stay in this session
|
||||||
|
- Fresh subagent per task + code review
|
||||||
|
|
||||||
|
**If Parallel Session chosen:**
|
||||||
|
- Guide them to open new session in worktree
|
||||||
|
- **REQUIRED SUB-SKILL:** New session uses superpowers:executing-plans
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
# 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 |
|
|
||||||
| File Structure | Files have clear single responsibilities, split by responsibility not layer |
|
|
||||||
| File Size | Would any new or modified file likely grow large enough to be hard to reason about as a whole? |
|
|
||||||
| Task Syntax | Checkbox syntax (`- [ ]`) on steps for tracking |
|
|
||||||
| 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
|
|
||||||
- Files planned to hold multiple responsibilities or likely to grow unwieldy
|
|
||||||
|
|
||||||
## 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
|
|
||||||
@@ -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.**
|
**Writing skills IS Test-Driven Development applied to process documentation.**
|
||||||
|
|
||||||
**Personal skills live in agent-specific directories (`~/.claude/skills` for Claude Code, `~/.agents/skills/` for Codex)**
|
**Personal skills live in agent-specific directories (`~/.claude/skills` for Claude Code, `~/.codex/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).
|
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).
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ const assert = require('assert');
|
|||||||
|
|
||||||
const SERVER_PATH = path.join(__dirname, '../../lib/brainstorm-server/index.js');
|
const SERVER_PATH = path.join(__dirname, '../../lib/brainstorm-server/index.js');
|
||||||
const TEST_PORT = 3334;
|
const TEST_PORT = 3334;
|
||||||
const TEST_DIR = '/tmp/brainstorm-test';
|
const TEST_SCREEN = '/tmp/brainstorm-test/screen.html';
|
||||||
|
|
||||||
|
// Clean up test directory
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
if (fs.existsSync(TEST_DIR)) {
|
if (fs.existsSync(path.dirname(TEST_SCREEN))) {
|
||||||
fs.rmSync(TEST_DIR, { recursive: true });
|
fs.rmSync(path.dirname(TEST_SCREEN), { recursive: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,29 +30,19 @@ async function fetch(url) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startServer() {
|
|
||||||
return spawn('node', [SERVER_PATH], {
|
|
||||||
env: { ...process.env, BRAINSTORM_PORT: TEST_PORT, BRAINSTORM_DIR: TEST_DIR }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runTests() {
|
async function runTests() {
|
||||||
cleanup();
|
cleanup();
|
||||||
fs.mkdirSync(TEST_DIR, { recursive: true });
|
|
||||||
|
|
||||||
const server = startServer();
|
// Start server
|
||||||
|
const server = spawn('node', [SERVER_PATH], {
|
||||||
|
env: { ...process.env, BRAINSTORM_PORT: TEST_PORT, BRAINSTORM_SCREEN: TEST_SCREEN }
|
||||||
|
});
|
||||||
|
|
||||||
let stdout = '';
|
let stdout = '';
|
||||||
let stderr = '';
|
|
||||||
server.stdout.on('data', (data) => { stdout += data.toString(); });
|
server.stdout.on('data', (data) => { stdout += data.toString(); });
|
||||||
server.stderr.on('data', (data) => { stderr += data.toString(); });
|
server.stderr.on('data', (data) => { console.error('Server stderr:', data.toString()); });
|
||||||
|
|
||||||
// Wait for server to start (up to 3 seconds)
|
await sleep(1000); // Wait for server to start
|
||||||
for (let i = 0; i < 30; i++) {
|
|
||||||
if (stdout.includes('server-started')) break;
|
|
||||||
await sleep(100);
|
|
||||||
}
|
|
||||||
if (stderr) console.error('Server stderr:', stderr);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Test 1: Server starts and outputs JSON
|
// Test 1: Server starts and outputs JSON
|
||||||
@@ -60,17 +51,17 @@ async function runTests() {
|
|||||||
assert(stdout.includes(TEST_PORT.toString()), 'Should include port');
|
assert(stdout.includes(TEST_PORT.toString()), 'Should include port');
|
||||||
console.log(' PASS');
|
console.log(' PASS');
|
||||||
|
|
||||||
// Test 2: GET / returns waiting page with helper injected when no screens exist
|
// Test 2: GET / returns HTML with helper injected
|
||||||
console.log('Test 2: Serves waiting page with helper injected');
|
console.log('Test 2: Serves HTML with helper injected');
|
||||||
const res = await fetch(`http://localhost:${TEST_PORT}/`);
|
const res = await fetch(`http://localhost:${TEST_PORT}/`);
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
assert(res.body.includes('Waiting for Claude'), 'Should show waiting message');
|
assert(res.body.includes('brainstorm'), 'Should include brainstorm content');
|
||||||
assert(res.body.includes('WebSocket'), 'Should have helper.js injected');
|
assert(res.body.includes('WebSocket'), 'Should have helper.js injected');
|
||||||
console.log(' PASS');
|
console.log(' PASS');
|
||||||
|
|
||||||
// Test 3: WebSocket connection and event relay
|
// Test 3: WebSocket connection and event relay
|
||||||
console.log('Test 3: WebSocket relays events to stdout');
|
console.log('Test 3: WebSocket relays events to stdout');
|
||||||
stdout = '';
|
stdout = ''; // Reset stdout capture
|
||||||
const ws = new WebSocket(`ws://localhost:${TEST_PORT}`);
|
const ws = new WebSocket(`ws://localhost:${TEST_PORT}`);
|
||||||
await new Promise(resolve => ws.on('open', resolve));
|
await new Promise(resolve => ws.on('open', resolve));
|
||||||
|
|
||||||
@@ -93,61 +84,14 @@ async function runTests() {
|
|||||||
if (msg.type === 'reload') gotReload = true;
|
if (msg.type === 'reload') gotReload = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.writeFileSync(path.join(TEST_DIR, 'test-screen.html'), '<html><body>Full doc</body></html>');
|
// Modify the screen file
|
||||||
|
fs.writeFileSync(TEST_SCREEN, '<html><body>Updated</body></html>');
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
|
|
||||||
assert(gotReload, 'Should send reload message on file change');
|
assert(gotReload, 'Should send reload message on file change');
|
||||||
ws2.close();
|
ws2.close();
|
||||||
console.log(' PASS');
|
console.log(' PASS');
|
||||||
|
|
||||||
// Test 5: Full HTML document served as-is (not wrapped)
|
|
||||||
console.log('Test 5: Full HTML document served without frame wrapping');
|
|
||||||
const fullDoc = '<!DOCTYPE html>\n<html><head><title>Custom</title></head><body><h1>Custom Page</h1></body></html>';
|
|
||||||
fs.writeFileSync(path.join(TEST_DIR, 'full-doc.html'), fullDoc);
|
|
||||||
await sleep(300);
|
|
||||||
|
|
||||||
const fullRes = await fetch(`http://localhost:${TEST_PORT}/`);
|
|
||||||
assert(fullRes.body.includes('<h1>Custom Page</h1>'), 'Should contain original content');
|
|
||||||
assert(fullRes.body.includes('WebSocket'), 'Should still inject helper.js');
|
|
||||||
// Should NOT have the frame template's feedback footer
|
|
||||||
assert(!fullRes.body.includes('feedback-footer') || fullDoc.includes('feedback-footer'),
|
|
||||||
'Should not wrap full documents in frame template');
|
|
||||||
console.log(' PASS');
|
|
||||||
|
|
||||||
// Test 6: Bare HTML fragment gets wrapped in frame template
|
|
||||||
console.log('Test 6: Content fragment wrapped in frame template');
|
|
||||||
const fragment = '<h2>Pick a layout</h2>\n<p class="subtitle">Choose one</p>\n<div class="options"><div class="option" data-choice="a"><div class="letter">A</div><div class="content"><h3>Simple</h3></div></div></div>';
|
|
||||||
fs.writeFileSync(path.join(TEST_DIR, 'fragment.html'), fragment);
|
|
||||||
await sleep(300);
|
|
||||||
|
|
||||||
const fragRes = await fetch(`http://localhost:${TEST_PORT}/`);
|
|
||||||
// Should have the frame template structure
|
|
||||||
assert(fragRes.body.includes('feedback-footer'), 'Fragment should get feedback footer from frame');
|
|
||||||
assert(fragRes.body.includes('Brainstorm Companion'), 'Fragment should get header from frame');
|
|
||||||
assert(fragRes.body.includes('--bg-primary'), 'Fragment should get theme CSS from frame');
|
|
||||||
// Should have the original content inside
|
|
||||||
assert(fragRes.body.includes('Pick a layout'), 'Fragment content should be present');
|
|
||||||
assert(fragRes.body.includes('data-choice="a"'), 'Fragment content should be intact');
|
|
||||||
// Should have helper.js injected
|
|
||||||
assert(fragRes.body.includes('WebSocket'), 'Fragment should have helper.js injected');
|
|
||||||
console.log(' PASS');
|
|
||||||
|
|
||||||
// Test 7: Helper.js includes toggleSelect and send functions
|
|
||||||
console.log('Test 7: Helper.js provides toggleSelect and send');
|
|
||||||
const helperContent = fs.readFileSync(
|
|
||||||
path.join(__dirname, '../../lib/brainstorm-server/helper.js'), 'utf-8'
|
|
||||||
);
|
|
||||||
assert(helperContent.includes('toggleSelect'), 'helper.js should define toggleSelect');
|
|
||||||
assert(helperContent.includes('send'), 'helper.js should define send function');
|
|
||||||
assert(helperContent.includes('selectedChoice'), 'helper.js should track selectedChoice');
|
|
||||||
console.log(' PASS');
|
|
||||||
|
|
||||||
// Test 8: sendToClaude confirmation uses CSS variables (dark mode support)
|
|
||||||
console.log('Test 8: sendToClaude confirmation respects theming');
|
|
||||||
assert(!helperContent.includes('color: #666'), 'Should not use hardcoded light-mode colors');
|
|
||||||
assert(!helperContent.includes('color: #333'), 'Should not use hardcoded light-mode colors');
|
|
||||||
console.log(' PASS');
|
|
||||||
|
|
||||||
console.log('\nAll tests passed!');
|
console.log('\nAll tests passed!');
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,177 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Integration Test: Document Review System
|
|
||||||
# Actually runs spec/plan review and verifies reviewers catch issues
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
||||||
source "$SCRIPT_DIR/test-helpers.sh"
|
|
||||||
|
|
||||||
echo "========================================"
|
|
||||||
echo " Integration Test: Document Review System"
|
|
||||||
echo "========================================"
|
|
||||||
echo ""
|
|
||||||
echo "This test verifies the document review system by:"
|
|
||||||
echo " 1. Creating a spec with intentional errors"
|
|
||||||
echo " 2. Running the spec document reviewer"
|
|
||||||
echo " 3. Verifying the reviewer catches the errors"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Create test project
|
|
||||||
TEST_PROJECT=$(create_test_project)
|
|
||||||
echo "Test project: $TEST_PROJECT"
|
|
||||||
|
|
||||||
# Trap to cleanup
|
|
||||||
trap "cleanup_test_project $TEST_PROJECT" EXIT
|
|
||||||
|
|
||||||
cd "$TEST_PROJECT"
|
|
||||||
|
|
||||||
# Create directory structure
|
|
||||||
mkdir -p docs/superpowers/specs
|
|
||||||
|
|
||||||
# Create a spec document WITH INTENTIONAL ERRORS for the reviewer to catch
|
|
||||||
cat > docs/superpowers/specs/test-feature-design.md <<'EOF'
|
|
||||||
# Test Feature Design
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This is a test feature that does something useful.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
1. The feature should work correctly
|
|
||||||
2. It should be fast
|
|
||||||
3. TODO: Add more requirements here
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
The feature will use a simple architecture with:
|
|
||||||
- A frontend component
|
|
||||||
- A backend service
|
|
||||||
- Error handling will be specified later once we understand the failure modes better
|
|
||||||
|
|
||||||
## Data Flow
|
|
||||||
|
|
||||||
Data flows from the frontend to the backend.
|
|
||||||
|
|
||||||
## Testing Strategy
|
|
||||||
|
|
||||||
Tests will be written to cover the main functionality.
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Initialize git repo
|
|
||||||
git init --quiet
|
|
||||||
git config user.email "test@test.com"
|
|
||||||
git config user.name "Test User"
|
|
||||||
git add .
|
|
||||||
git commit -m "Initial commit with test spec" --quiet
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Created test spec with intentional errors:"
|
|
||||||
echo " - TODO placeholder in Requirements section"
|
|
||||||
echo " - 'specified later' deferral in Architecture section"
|
|
||||||
echo ""
|
|
||||||
echo "Running spec document reviewer..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Run Claude to review the spec
|
|
||||||
OUTPUT_FILE="$TEST_PROJECT/claude-output.txt"
|
|
||||||
|
|
||||||
PROMPT="You are testing the spec document reviewer.
|
|
||||||
|
|
||||||
Read the spec-document-reviewer-prompt.md template in skills/brainstorming/ to understand the review format.
|
|
||||||
|
|
||||||
Then review the spec at $TEST_PROJECT/docs/superpowers/specs/test-feature-design.md using the criteria from that template.
|
|
||||||
|
|
||||||
Look for:
|
|
||||||
- TODOs, placeholders, 'TBD', incomplete sections
|
|
||||||
- Sections saying 'to be defined later' or 'will spec when X is done'
|
|
||||||
- Sections noticeably less detailed than others
|
|
||||||
|
|
||||||
Output your review in the format specified in the template."
|
|
||||||
|
|
||||||
echo "================================================================================"
|
|
||||||
cd "$SCRIPT_DIR/../.." && timeout 120 claude -p "$PROMPT" --permission-mode bypassPermissions 2>&1 | tee "$OUTPUT_FILE" || {
|
|
||||||
echo ""
|
|
||||||
echo "================================================================================"
|
|
||||||
echo "EXECUTION FAILED (exit code: $?)"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
echo "================================================================================"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Analyzing reviewer output..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Verification tests
|
|
||||||
FAILED=0
|
|
||||||
|
|
||||||
echo "=== Verification Tests ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Test 1: Reviewer found the TODO
|
|
||||||
echo "Test 1: Reviewer found TODO..."
|
|
||||||
if grep -qi "TODO" "$OUTPUT_FILE" && grep -qi "requirements\|Requirements" "$OUTPUT_FILE"; then
|
|
||||||
echo " [PASS] Reviewer identified TODO in Requirements section"
|
|
||||||
else
|
|
||||||
echo " [FAIL] Reviewer did not identify TODO"
|
|
||||||
FAILED=$((FAILED + 1))
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Test 2: Reviewer found the "specified later" deferral
|
|
||||||
echo "Test 2: Reviewer found 'specified later' deferral..."
|
|
||||||
if grep -qi "specified later\|later\|defer\|incomplete\|error handling" "$OUTPUT_FILE"; then
|
|
||||||
echo " [PASS] Reviewer identified deferred content"
|
|
||||||
else
|
|
||||||
echo " [FAIL] Reviewer did not identify deferred content"
|
|
||||||
FAILED=$((FAILED + 1))
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Test 3: Reviewer output includes Issues section
|
|
||||||
echo "Test 3: Review output format..."
|
|
||||||
if grep -qi "issues\|Issues" "$OUTPUT_FILE"; then
|
|
||||||
echo " [PASS] Review includes Issues section"
|
|
||||||
else
|
|
||||||
echo " [FAIL] Review missing Issues section"
|
|
||||||
FAILED=$((FAILED + 1))
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Test 4: Reviewer did NOT approve (found issues)
|
|
||||||
echo "Test 4: Reviewer verdict..."
|
|
||||||
if grep -qi "Issues Found\|❌\|not approved\|issues found" "$OUTPUT_FILE"; then
|
|
||||||
echo " [PASS] Reviewer correctly found issues (not approved)"
|
|
||||||
elif grep -qi "Approved\|✅" "$OUTPUT_FILE" && ! grep -qi "Issues Found\|❌" "$OUTPUT_FILE"; then
|
|
||||||
echo " [FAIL] Reviewer incorrectly approved spec with errors"
|
|
||||||
FAILED=$((FAILED + 1))
|
|
||||||
else
|
|
||||||
echo " [PASS] Reviewer identified problems (ambiguous format but found issues)"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
echo "========================================"
|
|
||||||
echo " Test Summary"
|
|
||||||
echo "========================================"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if [ $FAILED -eq 0 ]; then
|
|
||||||
echo "STATUS: PASSED"
|
|
||||||
echo "All verification tests passed!"
|
|
||||||
echo ""
|
|
||||||
echo "The spec document reviewer correctly:"
|
|
||||||
echo " ✓ Found TODO placeholder"
|
|
||||||
echo " ✓ Found 'specified later' deferral"
|
|
||||||
echo " ✓ Produced properly formatted review"
|
|
||||||
echo " ✓ Did not approve spec with errors"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "STATUS: FAILED"
|
|
||||||
echo "Failed $FAILED verification tests"
|
|
||||||
echo ""
|
|
||||||
echo "Output saved to: $OUTPUT_FILE"
|
|
||||||
echo ""
|
|
||||||
echo "Review the output to see what went wrong."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -143,7 +143,7 @@ cleanup_test_project() {
|
|||||||
create_test_plan() {
|
create_test_plan() {
|
||||||
local project_dir="$1"
|
local project_dir="$1"
|
||||||
local plan_name="${2:-test-plan}"
|
local plan_name="${2:-test-plan}"
|
||||||
local plan_file="$project_dir/docs/superpowers/plans/$plan_name.md"
|
local plan_file="$project_dir/docs/plans/$plan_name.md"
|
||||||
|
|
||||||
mkdir -p "$(dirname "$plan_file")"
|
mkdir -p "$(dirname "$plan_file")"
|
||||||
|
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ cat > package.json <<'EOF'
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
mkdir -p src test docs/superpowers/plans
|
mkdir -p src test docs/plans
|
||||||
|
|
||||||
# Create a simple implementation plan
|
# Create a simple implementation plan
|
||||||
cat > docs/superpowers/plans/implementation-plan.md <<'EOF'
|
cat > docs/plans/implementation-plan.md <<'EOF'
|
||||||
# Test Implementation Plan
|
# Test Implementation Plan
|
||||||
|
|
||||||
This is a minimal plan to test the subagent-driven-development workflow.
|
This is a minimal plan to test the subagent-driven-development workflow.
|
||||||
@@ -121,7 +121,7 @@ OUTPUT_FILE="$TEST_PROJECT/claude-output.txt"
|
|||||||
|
|
||||||
# Create prompt file
|
# Create prompt file
|
||||||
cat > "$TEST_PROJECT/prompt.txt" <<'EOF'
|
cat > "$TEST_PROJECT/prompt.txt" <<'EOF'
|
||||||
I want you to execute the implementation plan at docs/superpowers/plans/implementation-plan.md using the subagent-driven-development skill.
|
I want you to execute the implementation plan at docs/plans/implementation-plan.md using the subagent-driven-development skill.
|
||||||
|
|
||||||
IMPORTANT: Follow the skill exactly. I will be verifying that you:
|
IMPORTANT: Follow the skill exactly. I will be verifying that you:
|
||||||
1. Read the plan once at the beginning
|
1. Read the plan once at the beginning
|
||||||
@@ -136,7 +136,7 @@ EOF
|
|||||||
# Note: We use a longer timeout since this is integration testing
|
# Note: We use a longer timeout since this is integration testing
|
||||||
# Use --allowed-tools to enable tool usage in headless mode
|
# Use --allowed-tools to enable tool usage in headless mode
|
||||||
# IMPORTANT: Run from superpowers directory so local dev skills are available
|
# IMPORTANT: Run from superpowers directory so local dev skills are available
|
||||||
PROMPT="Change to directory $TEST_PROJECT and then execute the implementation plan at docs/superpowers/plans/implementation-plan.md using the subagent-driven-development skill.
|
PROMPT="Change to directory $TEST_PROJECT and then execute the implementation plan at docs/plans/implementation-plan.md using the subagent-driven-development skill.
|
||||||
|
|
||||||
IMPORTANT: Follow the skill exactly. I will be verifying that you:
|
IMPORTANT: Follow the skill exactly. I will be verifying that you:
|
||||||
1. Read the plan once at the beginning
|
1. Read the plan once at the beginning
|
||||||
|
|||||||
@@ -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)
|
output=$(run_claude "What is the subagent-driven-development skill? Describe its key steps briefly." 30)
|
||||||
|
|
||||||
if assert_contains "$output" "subagent-driven-development\|Subagent-Driven Development\|Subagent Driven" "Skill is recognized"; then
|
if assert_contains "$output" "subagent-driven-development" "Skill is recognized"; then
|
||||||
: # pass
|
: # pass
|
||||||
else
|
else
|
||||||
exit 1
|
exit 1
|
||||||
@@ -136,30 +136,4 @@ fi
|
|||||||
|
|
||||||
echo ""
|
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 ==="
|
echo "=== All subagent-driven-development skill tests passed ==="
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
The plan is done. docs/superpowers/plans/auth-system.md has everything.
|
The plan is done. docs/plans/auth-system.md has everything.
|
||||||
|
|
||||||
Do subagent-driven development on this - start with Task 1, dispatch a subagent, then we'll review.
|
Do subagent-driven development on this - start with Task 1, dispatch a subagent, then we'll review.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Great, the plan is complete. I've saved it to docs/superpowers/plans/auth-system.md.
|
Great, the plan is complete. I've saved it to docs/plans/auth-system.md.
|
||||||
|
|
||||||
Here's a summary of what we designed:
|
Here's a summary of what we designed:
|
||||||
- Task 1: Add User Model with email/password fields
|
- Task 1: Add User Model with email/password fields
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Previous assistant message]:
|
[Previous assistant message]:
|
||||||
Plan complete and saved to docs/superpowers/plans/auth-system.md.
|
Plan complete and saved to docs/plans/auth-system.md.
|
||||||
|
|
||||||
Two execution options:
|
Two execution options:
|
||||||
1. Subagent-Driven (this session) - I dispatch a fresh subagent per task, review between tasks, fast iteration within this conversation
|
1. Subagent-Driven (this session) - I dispatch a fresh subagent per task, review between tasks, fast iteration within this conversation
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
I have my implementation plan ready at docs/superpowers/plans/auth-system.md.
|
I have my implementation plan ready at docs/plans/auth-system.md.
|
||||||
|
|
||||||
I want to use subagent-driven-development to execute it. That means:
|
I want to use subagent-driven-development to execute it. That means:
|
||||||
- Dispatch a fresh subagent for each task in the plan
|
- Dispatch a fresh subagent for each task in the plan
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
I have a plan at docs/superpowers/plans/auth-system.md that's ready to implement.
|
I have a plan at docs/plans/auth-system.md that's ready to implement.
|
||||||
|
|
||||||
subagent-driven-development, please
|
subagent-driven-development, please
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
Plan is at docs/superpowers/plans/auth-system.md.
|
Plan is at docs/plans/auth-system.md.
|
||||||
|
|
||||||
subagent-driven-development, please. Don't waste time - just read the plan and start dispatching subagents immediately.
|
subagent-driven-development, please. Don't waste time - just read the plan and start dispatching subagents immediately.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ OUTPUT_DIR="/tmp/superpowers-tests/${TIMESTAMP}/explicit-skill-requests/claude-d
|
|||||||
mkdir -p "$OUTPUT_DIR"
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
PROJECT_DIR="$OUTPUT_DIR/project"
|
PROJECT_DIR="$OUTPUT_DIR/project"
|
||||||
mkdir -p "$PROJECT_DIR/docs/superpowers/plans"
|
mkdir -p "$PROJECT_DIR/docs/plans"
|
||||||
|
|
||||||
echo "=== Test: Claude Describes SDD First ==="
|
echo "=== Test: Claude Describes SDD First ==="
|
||||||
echo "Output dir: $OUTPUT_DIR"
|
echo "Output dir: $OUTPUT_DIR"
|
||||||
@@ -21,7 +21,7 @@ echo ""
|
|||||||
cd "$PROJECT_DIR"
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
# Create a plan
|
# Create a plan
|
||||||
cat > "$PROJECT_DIR/docs/superpowers/plans/auth-system.md" << 'EOF'
|
cat > "$PROJECT_DIR/docs/plans/auth-system.md" << 'EOF'
|
||||||
# Auth System Implementation Plan
|
# Auth System Implementation Plan
|
||||||
|
|
||||||
## Task 1: Add User Model
|
## Task 1: Add User Model
|
||||||
@@ -36,7 +36,7 @@ EOF
|
|||||||
|
|
||||||
# Turn 1: Have Claude describe execution options including SDD
|
# Turn 1: Have Claude describe execution options including SDD
|
||||||
echo ">>> Turn 1: Ask Claude to describe execution options..."
|
echo ">>> Turn 1: Ask Claude to describe execution options..."
|
||||||
claude -p "I have a plan at docs/superpowers/plans/auth-system.md. Tell me about my options for executing it, including what subagent-driven-development means and how it works." \
|
claude -p "I have a plan at docs/plans/auth-system.md. Tell me about my options for executing it, including what subagent-driven-development means and how it works." \
|
||||||
--model haiku \
|
--model haiku \
|
||||||
--plugin-dir "$PLUGIN_DIR" \
|
--plugin-dir "$PLUGIN_DIR" \
|
||||||
--dangerously-skip-permissions \
|
--dangerously-skip-permissions \
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ OUTPUT_DIR="/tmp/superpowers-tests/${TIMESTAMP}/explicit-skill-requests/extended
|
|||||||
mkdir -p "$OUTPUT_DIR"
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
PROJECT_DIR="$OUTPUT_DIR/project"
|
PROJECT_DIR="$OUTPUT_DIR/project"
|
||||||
mkdir -p "$PROJECT_DIR/docs/superpowers/plans"
|
mkdir -p "$PROJECT_DIR/docs/plans"
|
||||||
|
|
||||||
echo "=== Extended Multi-Turn Test ==="
|
echo "=== Extended Multi-Turn Test ==="
|
||||||
echo "Output dir: $OUTPUT_DIR"
|
echo "Output dir: $OUTPUT_DIR"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ OUTPUT_DIR="/tmp/superpowers-tests/${TIMESTAMP}/explicit-skill-requests/haiku"
|
|||||||
mkdir -p "$OUTPUT_DIR"
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
PROJECT_DIR="$OUTPUT_DIR/project"
|
PROJECT_DIR="$OUTPUT_DIR/project"
|
||||||
mkdir -p "$PROJECT_DIR/docs/superpowers/plans"
|
mkdir -p "$PROJECT_DIR/docs/plans"
|
||||||
mkdir -p "$PROJECT_DIR/.claude"
|
mkdir -p "$PROJECT_DIR/.claude"
|
||||||
|
|
||||||
echo "=== Haiku Model Test with User CLAUDE.md ==="
|
echo "=== Haiku Model Test with User CLAUDE.md ==="
|
||||||
@@ -31,7 +31,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Create a dummy plan file
|
# Create a dummy plan file
|
||||||
cat > "$PROJECT_DIR/docs/superpowers/plans/auth-system.md" << 'EOF'
|
cat > "$PROJECT_DIR/docs/plans/auth-system.md" << 'EOF'
|
||||||
# Auth System Implementation Plan
|
# Auth System Implementation Plan
|
||||||
|
|
||||||
## Task 1: Add User Model
|
## Task 1: Add User Model
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ mkdir -p "$OUTPUT_DIR"
|
|||||||
|
|
||||||
# Create project directory (conversation is cwd-based)
|
# Create project directory (conversation is cwd-based)
|
||||||
PROJECT_DIR="$OUTPUT_DIR/project"
|
PROJECT_DIR="$OUTPUT_DIR/project"
|
||||||
mkdir -p "$PROJECT_DIR/docs/superpowers/plans"
|
mkdir -p "$PROJECT_DIR/docs/plans"
|
||||||
|
|
||||||
echo "=== Multi-Turn Explicit Skill Request Test ==="
|
echo "=== Multi-Turn Explicit Skill Request Test ==="
|
||||||
echo "Output dir: $OUTPUT_DIR"
|
echo "Output dir: $OUTPUT_DIR"
|
||||||
@@ -27,7 +27,7 @@ echo ""
|
|||||||
cd "$PROJECT_DIR"
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
# Create a dummy plan file
|
# Create a dummy plan file
|
||||||
cat > "$PROJECT_DIR/docs/superpowers/plans/auth-system.md" << 'EOF'
|
cat > "$PROJECT_DIR/docs/plans/auth-system.md" << 'EOF'
|
||||||
# Auth System Implementation Plan
|
# Auth System Implementation Plan
|
||||||
|
|
||||||
## Task 1: Add User Model
|
## Task 1: Add User Model
|
||||||
@@ -59,7 +59,7 @@ echo ""
|
|||||||
# Turn 2: Continue with more planning detail
|
# Turn 2: Continue with more planning detail
|
||||||
echo ">>> Turn 2: Continuing planning..."
|
echo ">>> Turn 2: Continuing planning..."
|
||||||
TURN2_LOG="$OUTPUT_DIR/turn2.json"
|
TURN2_LOG="$OUTPUT_DIR/turn2.json"
|
||||||
claude -p "Good analysis. I've already written the plan to docs/superpowers/plans/auth-system.md. Now I'm ready to implement. What are my options for execution?" \
|
claude -p "Good analysis. I've already written the plan to docs/plans/auth-system.md. Now I'm ready to implement. What are my options for execution?" \
|
||||||
--continue \
|
--continue \
|
||||||
--plugin-dir "$PLUGIN_DIR" \
|
--plugin-dir "$PLUGIN_DIR" \
|
||||||
--dangerously-skip-permissions \
|
--dangerously-skip-permissions \
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ cp "$PROMPT_FILE" "$OUTPUT_DIR/prompt.txt"
|
|||||||
|
|
||||||
# Create a minimal project directory for the test
|
# Create a minimal project directory for the test
|
||||||
PROJECT_DIR="$OUTPUT_DIR/project"
|
PROJECT_DIR="$OUTPUT_DIR/project"
|
||||||
mkdir -p "$PROJECT_DIR/docs/superpowers/plans"
|
mkdir -p "$PROJECT_DIR/docs/plans"
|
||||||
|
|
||||||
# Create a dummy plan file for mid-conversation tests
|
# Create a dummy plan file for mid-conversation tests
|
||||||
cat > "$PROJECT_DIR/docs/superpowers/plans/auth-system.md" << 'EOF'
|
cat > "$PROJECT_DIR/docs/plans/auth-system.md" << 'EOF'
|
||||||
# Auth System Implementation Plan
|
# Auth System Implementation Plan
|
||||||
|
|
||||||
## Task 1: Add User Model
|
## Task 1: Add User Model
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ cp -r "$REPO_ROOT/lib" "$HOME/.config/opencode/superpowers/"
|
|||||||
cp -r "$REPO_ROOT/skills" "$HOME/.config/opencode/superpowers/"
|
cp -r "$REPO_ROOT/skills" "$HOME/.config/opencode/superpowers/"
|
||||||
|
|
||||||
# Copy plugin directory
|
# Copy plugin directory
|
||||||
mkdir -p "$HOME/.config/opencode/superpowers/.opencode/plugins"
|
mkdir -p "$HOME/.config/opencode/superpowers/.opencode/plugin"
|
||||||
cp "$REPO_ROOT/.opencode/plugins/superpowers.js" "$HOME/.config/opencode/superpowers/.opencode/plugins/"
|
cp "$REPO_ROOT/.opencode/plugin/superpowers.js" "$HOME/.config/opencode/superpowers/.opencode/plugin/"
|
||||||
|
|
||||||
# Register plugin via symlink
|
# Register plugin via symlink
|
||||||
mkdir -p "$HOME/.config/opencode/plugins"
|
mkdir -p "$HOME/.config/opencode/plugin"
|
||||||
ln -sf "$HOME/.config/opencode/superpowers/.opencode/plugins/superpowers.js" \
|
ln -sf "$HOME/.config/opencode/superpowers/.opencode/plugin/superpowers.js" \
|
||||||
"$HOME/.config/opencode/plugins/superpowers.js"
|
"$HOME/.config/opencode/plugin/superpowers.js"
|
||||||
|
|
||||||
# Create test skills in different locations for testing
|
# Create test skills in different locations for testing
|
||||||
|
|
||||||
@@ -57,8 +57,8 @@ PROJECT_SKILL_MARKER_67890
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "Setup complete: $TEST_HOME"
|
echo "Setup complete: $TEST_HOME"
|
||||||
echo "Plugin installed to: $HOME/.config/opencode/superpowers/.opencode/plugins/superpowers.js"
|
echo "Plugin installed to: $HOME/.config/opencode/superpowers/.opencode/plugin/superpowers.js"
|
||||||
echo "Plugin registered at: $HOME/.config/opencode/plugins/superpowers.js"
|
echo "Plugin registered at: $HOME/.config/opencode/plugin/superpowers.js"
|
||||||
echo "Test project at: $TEST_HOME/test-project"
|
echo "Test project at: $TEST_HOME/test-project"
|
||||||
|
|
||||||
# Helper function for cleanup (call from tests or trap)
|
# Helper function for cleanup (call from tests or trap)
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ trap cleanup_test_env EXIT
|
|||||||
|
|
||||||
# Test 1: Verify plugin file exists and is registered
|
# Test 1: Verify plugin file exists and is registered
|
||||||
echo "Test 1: Checking plugin registration..."
|
echo "Test 1: Checking plugin registration..."
|
||||||
if [ -L "$HOME/.config/opencode/plugins/superpowers.js" ]; then
|
if [ -L "$HOME/.config/opencode/plugin/superpowers.js" ]; then
|
||||||
echo " [PASS] Plugin symlink exists"
|
echo " [PASS] Plugin symlink exists"
|
||||||
else
|
else
|
||||||
echo " [FAIL] Plugin symlink not found at $HOME/.config/opencode/plugins/superpowers.js"
|
echo " [FAIL] Plugin symlink not found at $HOME/.config/opencode/plugin/superpowers.js"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify symlink target exists
|
# Verify symlink target exists
|
||||||
if [ -f "$(readlink -f "$HOME/.config/opencode/plugins/superpowers.js")" ]; then
|
if [ -f "$(readlink -f "$HOME/.config/opencode/plugin/superpowers.js")" ]; then
|
||||||
echo " [PASS] Plugin symlink target exists"
|
echo " [PASS] Plugin symlink target exists"
|
||||||
else
|
else
|
||||||
echo " [FAIL] Plugin symlink target does not exist"
|
echo " [FAIL] Plugin symlink target does not exist"
|
||||||
@@ -60,7 +60,7 @@ fi
|
|||||||
|
|
||||||
# Test 5: Verify plugin JavaScript syntax (basic check)
|
# Test 5: Verify plugin JavaScript syntax (basic check)
|
||||||
echo "Test 5: Checking plugin JavaScript syntax..."
|
echo "Test 5: Checking plugin JavaScript syntax..."
|
||||||
plugin_file="$HOME/.config/opencode/superpowers/.opencode/plugins/superpowers.js"
|
plugin_file="$HOME/.config/opencode/superpowers/.opencode/plugin/superpowers.js"
|
||||||
if node --check "$plugin_file" 2>/dev/null; then
|
if node --check "$plugin_file" 2>/dev/null; then
|
||||||
echo " [PASS] Plugin JavaScript syntax is valid"
|
echo " [PASS] Plugin JavaScript syntax is valid"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
I have a plan document at docs/superpowers/plans/2024-01-15-auth-system.md that needs to be executed. Please implement it.
|
I have a plan document at docs/plans/2024-01-15-auth-system.md that needs to be executed. Please implement it.
|
||||||
Reference in New Issue
Block a user