diff --git a/.codebuddy/INSTALL.md b/.codebuddy/INSTALL.md new file mode 100644 index 000000000..4a8521ca0 --- /dev/null +++ b/.codebuddy/INSTALL.md @@ -0,0 +1,269 @@ +# Superpowers Installation Guide for CodeBuddy + +## Quick Install (One-Command) + +Tell CodeBuddy in Craft mode: + +``` +Fetch and follow instructions from https://raw.githubusercontent.com/binbinao/superpowers/refs/heads/main/.codebuddy/INSTALL.md +``` + +Or run these commands in your terminal: + +```bash +# Clone superpowers +mkdir -p ~/.codebuddy +git clone https://github.com/binbinao/superpowers.git ~/.codebuddy/superpowers + +# Install MCP server dependencies +cd ~/.codebuddy/superpowers/.codebuddy/mcp-server +npm install + +# Verify installation +node test.js +``` + +## Manual Installation + +### Step 1: Clone Repository + +```bash +mkdir -p ~/.codebuddy +git clone https://github.com/binbinao/superpowers.git ~/.codebuddy/superpowers +cd ~/.codebuddy/superpowers +``` + +### Step 2: Install Dependencies + +```bash +cd .codebuddy/mcp-server +npm install +``` + +### Step 3: Configure MCP in CodeBuddy + +#### For VS Code Plugin: + +1. Open VS Code with CodeBuddy plugin installed +2. Click CodeBuddy icon in the sidebar +3. Select **Craft** mode +4. Click **MCP** option +5. Click **Add MCP Server** or **Configure** +6. Add new server with these settings: + +**Method A: Using npx (Easiest)** + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "github.com/binbinao/superpowers#main/.codebuddy/mcp-server" + ], + "disabled": false +} +``` + +**Method B: Using local installation** + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": ["/Users/YOUR_HOME/.codebuddy/superpowers/.codebuddy/mcp-server/index.js"], + "disabled": false +} +``` + +Replace `/Users/YOUR_HOME` with your actual home directory (run `echo ~` to see it). + +#### For JetBrains Plugin: + +1. Open CodeBuddy settings in your JetBrains IDE +2. Navigate to **MCP Configuration** +3. Add new server with same settings as above + +#### For Internal Version: + +The internal version of CodeBuddy supports additional configuration options: + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": ["/Users/YOUR_HOME/.codebuddy/superpowers/.codebuddy/mcp-server/index.js"], + "disabled": false, + "configSource": "user", + "timeout": 60 +} +``` + +### Step 4: Restart CodeBuddy + +Restart CodeBuddy to load the MCP server. + +### Step 5: Verify Installation + +In CodeBuddy Craft mode, ask: + +``` +Use find_skills tool to list all available superpowers skills +``` + +You should see a list of available skills. + +## Verification + +Run the test suite: + +```bash +cd ~/.codebuddy/superpowers/.codebuddy/mcp-server +node test.js +``` + +All tests should pass with ✓ marks. + +## Usage Examples + +### Load a Skill + +``` +Use use_skill tool with skill_name: "superpowers:brainstorming" +``` + +### Find Available Skills + +``` +Use find_skills tool +``` + +### Get Bootstrap + +``` +Use get_bootstrap tool +``` + +## Creating Personal Skills + +Create your own skills in `~/.config/codebuddy/skills/`: + +```bash +mkdir -p ~/.config/codebuddy/skills/my-skill +cat > ~/.config/codebuddy/skills/my-skill/SKILL.md << 'EOF' +--- +name: my-skill +description: Use when [condition] - [what it does] +--- + +# My Skill + +[Your skill content here] +EOF +``` + +Then use it: `use_skill tool with skill_name: "my-skill"` + +## Creating Project Skills + +For project-specific skills, create them in your project directory: + +```bash +mkdir -p .codebuddy/skills/my-project-skill +cat > .codebuddy/skills/my-project-skill/SKILL.md << 'EOF' +--- +name: my-project-skill +description: Use when [condition] - [what it does] +--- + +# My Project Skill + +[Your skill content here] +EOF +``` + +Then use: `use_skill tool with skill_name: "project:my-project-skill"` + +## Skill Priority + +When you use `use_skill` with a skill name: + +1. **Project skills** (`.codebuddy/skills/`) - Checked first +2. **Personal skills** (`~/.config/codebuddy/skills/`) - Checked second +3. **Superpowers skills** (`~/.codebuddy/superpowers/skills/`) - Checked last + +Force specific skill type: +- `project:skill-name` - Only check project skills +- `skill-name` - Check project → personal → superpowers +- `superpowers:skill-name` - Only check superpowers skills + +## Troubleshooting + +### Installation Fails + +```bash +# Check Node.js version +node --version # Should be 18+ + +# Verify git clone worked +ls ~/.codebuddy/superpowers + +# Check npm install worked +ls ~/.codebuddy/superpowers/.codebuddy/mcp-server/node_modules +``` + +### MCP Server Won't Start + +```bash +# Test manually +node ~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js + +# Check for errors +# Should see: "Superpowers MCP server running on stdio" +``` + +### Skills Not Found + +```bash +# Run test to verify skills discovery +cd ~/.codebuddy/superpowers/.codebuddy/mcp-server +node test.js + +# Should show "Found XX skills" +``` + +### CodeBuddy Can't Connect to MCP + +1. Check CodeBuddy version (requires recent version with MCP support) +2. Verify MCP configuration file syntax is correct JSON +3. Check file paths are absolute (not relative) +4. Enable debug logging in CodeBuddy to see error messages +5. Try disabling and re-enabling the MCP server + +## Next Steps + +- Read full documentation: [docs/README.codebuddy.md](../docs/README.codebuddy.md) +- Learn skill development: [skills/writing-skills/SKILL.md](../skills/writing-skills/SKILL.md) +- Browse available skills: [skills/](../skills/) +- Report issues: [https://github.com/binbinao/superpowers/issues](https://github.com/binbinao/superpowers/issues) + +## Uninstallation + +```bash +# Remove the superpowers repository +rm -rf ~/.codebuddy/superpowers + +# Remove MCP configuration from CodeBuddy settings +# (Go to CodeBuddy MCP settings and delete superpowers server) +``` + +Your personal and project skills in `~/.config/codebuddy/skills/` and `.codebuddy/skills/` will remain unless you delete them. + +## Support + +- **Issues**: https://github.com/binbinao/superpowers/issues +- **CodeBuddy Docs**: https://cloud.tencent.com/document/product/1749 +- **CodeBuddy MCP Guide**: https://cloud.tencent.com/developer/article/2526313 diff --git a/.codebuddy/mcp-server/README.md b/.codebuddy/mcp-server/README.md new file mode 100644 index 000000000..77a8cb3f4 --- /dev/null +++ b/.codebuddy/mcp-server/README.md @@ -0,0 +1,189 @@ +# Superpowers MCP Server for CodeBuddy + +This directory contains the MCP (Model Context Protocol) server that integrates Superpowers skills with CodeBuddy. + +## Quick Start + +```bash +# Install dependencies +npm install + +# Test the server +node test.js + +# Run the server (for MCP client) +node index.js +``` + +## Configuration + +### CodeBuddy Configuration + +Add to CodeBuddy's MCP settings: + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": ["/absolute/path/to/.codebuddy/superpowers/.codebuddy/mcp-server/index.js"], + "disabled": false, + "configSource": "user", + "timeout": 60 +} +``` + +### Environment Setup + +The MCP server searches for skills in the following directories (priority order): + +1. `~/.codebuddy/skills/` - Project skills (highest priority) +2. `~/.config/codebuddy/skills/` - Personal skills +3. `/skills/` - Superpowers core skills + +## MCP Tools + +### `use_skill` + +Loads a specific skill's content into the conversation. + +**Parameters:** +- `skill_name` (string, required): Name of the skill to load + +**Examples:** +- `superpowers:brainstorming` - Load brainstorming skill from superpowers +- `my-custom-skill` - Load personal or project skill +- `project:my-skill` - Force load from project skills + +**Returns:** +- Skill content with metadata and supporting directory information + +### `find_skills` + +Lists all available skills across all skill directories. + +**Parameters:** +- None + +**Returns:** +- List of all skills with names, descriptions, and directory paths + +### `get_bootstrap` + +Gets the Superpowers bootstrap content including using-superpowers skill and tool mappings. + +**Parameters:** +- `compact` (boolean, optional): Use compact version (for after context compaction) + +**Returns:** +- Bootstrap content with using-superpowers skill loaded + +## Architecture + +### Shared Core Module + +The MCP server uses `lib/skills-core.js` for skill discovery and parsing, sharing this logic with OpenCode and Codex implementations. + +**Functions:** +- `extractFrontmatter(filePath)` - Parse YAML frontmatter +- `stripFrontmatter(content)` - Remove frontmatter from skill content +- `findSkillsInDir(dir, sourceType, maxDepth)` - Recursively discover skills +- `resolveSkillPath(skillName, superpowersDir, personalDir)` - Resolve skill with shadowing +- `checkForUpdates(repoDir)` - Check for git updates + +### Skill Loading Flow + +1. User calls `use_skill` with skill name +2. Server resolves skill path (project → personal → superpowers) +3. Reads SKILL.md file +4. Extracts metadata (name, description) +5. Strips frontmatter +6. Returns formatted skill content with directory information + +### Bootstrap Flow + +1. CodeBuddy starts session +2. Optionally calls `get_bootstrap` (compact: false) +3. Server loads using-superpowers skill +4. Adds tool mapping instructions +5. Returns complete bootstrap content + +## Development + +### Running Tests + +```bash +node test.js +``` + +This tests: +- Shared skills-core module loading +- Skill discovery +- Skill parsing (frontmatter) +- Skill resolution (with shadowing) +- Bootstrap generation +- Tool schemas +- Directory structure + +### Adding New Tools + +To add a new MCP tool: + +1. Add tool definition to `ListToolsRequestSchema` handler +2. Add implementation in `CallToolRequestSchema` handler +3. Update test.js to include new tool test +4. Update documentation + +Example: + +```javascript +// In ListToolsRequestSchema handler +{ + name: 'new_tool', + description: 'Description of what the tool does', + inputSchema: { + type: 'object', + properties: { + param1: { type: 'string', description: '...' } + }, + required: ['param1'] + } +} + +// In CallToolRequestSchema handler +if (name === 'new_tool') { + const { param1 } = args; + // Implementation + return { content: [{ type: 'text', text: result }] }; +} +``` + +## Troubleshooting + +### Server Won't Start + +1. Check Node.js version: `node --version` (needs 18+) +2. Verify dependencies: `ls node_modules/@modelcontextprotocol` +3. Check file paths in configuration are absolute paths +4. Run test.js to verify core functionality + +### Skills Not Found + +1. Verify superpowers/skills/ directory exists +2. Check file permissions +3. Run `find_skills` tool to see what's discovered +4. Check skill files have SKILL.md with proper frontmatter + +### MCP Connection Issues + +1. Verify CodeBuddy supports MCP (check version) +2. Check MCP server is configured correctly +3. Enable debug logging in CodeBuddy +4. Try running server manually to see error messages + +## Related Documentation + +- Main documentation: `docs/README.codebuddy.md` +- Skill development: `skills/writing-skills/SKILL.md` +- Superpowers README: `README.md` +- CodeBuddy MCP guide: https://cloud.tencent.com/developer/article/2526313 diff --git a/.codebuddy/mcp-server/index.js b/.codebuddy/mcp-server/index.js new file mode 100644 index 000000000..c7a7d2a5d --- /dev/null +++ b/.codebuddy/mcp-server/index.js @@ -0,0 +1,285 @@ +#!/usr/bin/env node + +/** + * Superpowers MCP Server for CodeBuddy + * + * This MCP server provides tools for loading and discovering Superpowers skills + * within CodeBuddy, enabling the same skill system that works with Claude Code, + * OpenCode, and Codex. + */ + +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { + CallToolRequestSchema, + ListToolsRequestSchema, +} from '@modelcontextprotocol/sdk/types.js'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import os from 'os'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// Import shared skills core +const skillsCoreModule = path.join(__dirname, '../../lib/skills-core.js'); +const { extractFrontmatter, stripFrontmatter, findSkillsInDir, resolveSkillPath, checkForUpdates } = await import( + 'file://' + skillsCoreModule +); + +// Create MCP server +const server = new Server( + { + name: 'superpowers', + version: '1.0.0', + }, + { + capabilities: { + tools: {}, + }, + } +); + +// Helper to get skill directories +const getSkillDirectories = () => { + const homeDir = os.homedir(); + + // Multiple search paths for skills (in priority order) + const searchPaths = [ + path.join(homeDir, '.codebuddy', 'skills'), // Project/local skills + path.join(homeDir, '.config', 'codebuddy', 'skills'), // Global CodeBuddy skills + path.join(__dirname, '../../skills'), // Superpowers core skills + ]; + + return { + superpowersSkillsDir: path.join(__dirname, '../../skills'), + personalSkillsDir: path.join(homeDir, '.config', 'codebuddy', 'skills'), + projectSkillsDir: path.join(homeDir, '.codebuddy', 'skills'), + superpowersRepoDir: path.join(homeDir, '.codebuddy', 'superpowers'), + }; +}; + +// Helper to generate bootstrap content +const getBootstrapContent = (compact = false) => { + const { superpowersSkillsDir, personalSkillsDir } = getSkillDirectories(); + const usingSuperpowersPath = resolveSkillPath('using-superpowers', superpowersSkillsDir, personalSkillsDir); + + if (!usingSuperpowersPath) return null; + + const fullContent = fs.readFileSync(usingSuperpowersPath.skillFile, 'utf8'); + const content = stripFrontmatter(fullContent); + + const toolMapping = compact + ? `**Tool Mapping:** TodoWrite->todo_write, Task->task, Skill->use_skill + +**Skills naming (priority order):** project: > personal > superpowers:` + : `**Tool Mapping for CodeBuddy:** +When skills reference tools you don't have, substitute CodeBuddy equivalents: +- \`TodoWrite\` → \`todo_write\` +- \`Task\` tool with subagents → Use CodeBuddy's task system +- \`Skill\` tool → \`use_skill\` MCP tool +- \`Read\`, \`Write\`, \`Edit\`, \`Bash\` → Your native tools + +**Skills naming (priority order):** +- Project skills: \`project:skill-name\` (in .codebuddy/skills/ or ~/.config/codebuddy/skills/) +- Personal skills: \`skill-name\` (in ~/.config/codebuddy/skills/) +- Superpowers skills: \`superpowers:skill-name\` +- Project skills override personal, which override superpowers when names match`; + + return ` +You have superpowers. + +**IMPORTANT: The using-superpowers skill content is included below. It is ALREADY LOADED - you are currently following it. Do NOT use the use_skill tool to load "using-superpowers" - that would be redundant. Use use_skill only for OTHER skills.** + +${content} + +${toolMapping} +`; +}; + +// List available tools +server.setRequestHandler(ListToolsRequestSchema, async () => { + return { + tools: [ + { + name: 'use_skill', + description: 'Load and read a specific skill to guide your work. Skills contain proven workflows, mandatory processes, and expert techniques.', + inputSchema: { + type: 'object', + properties: { + skill_name: { + type: 'string', + description: 'Name of the skill to load (e.g., "superpowers:brainstorming", "my-custom-skill", or "project:my-skill")' + } + }, + required: ['skill_name'] + } + }, + { + name: 'find_skills', + description: 'List all available skills in the project, personal, and superpowers skill libraries.', + inputSchema: { + type: 'object', + properties: {} + } + }, + { + name: 'get_bootstrap', + description: 'Get the Superpowers bootstrap content with using-superpowers skill and tool mappings.', + inputSchema: { + type: 'object', + properties: { + compact: { + type: 'boolean', + description: 'Use compact version (after context compaction)', + default: false + } + } + } + } + ] + }; +}); + +// Handle tool execution +server.setRequestHandler(CallToolRequestSchema, async (request) => { + const { name, arguments: args } = request.params; + + if (name === 'use_skill') { + const { skill_name } = args; + const { superpowersSkillsDir, personalSkillsDir, projectSkillsDir } = getSkillDirectories(); + + // Resolve with priority: project > personal > superpowers + const forceProject = skill_name.startsWith('project:'); + const actualSkillName = forceProject ? skill_name.replace(/^project:/, '') : skill_name; + + let resolved = null; + + // Try project skills first + if (forceProject || !skill_name.startsWith('superpowers:')) { + const projectPath = path.join(projectSkillsDir, actualSkillName); + const projectSkillFile = path.join(projectPath, 'SKILL.md'); + if (fs.existsSync(projectSkillFile)) { + resolved = { + skillFile: projectSkillFile, + sourceType: 'project', + skillPath: actualSkillName + }; + } + } + + // Fall back to personal/superpowers resolution + if (!resolved && !forceProject) { + resolved = resolveSkillPath(skill_name, superpowersSkillsDir, personalSkillsDir); + } + + if (!resolved) { + throw new Error(`Skill "${skill_name}" not found. Run find_skills to see available skills.`); + } + + const fullContent = fs.readFileSync(resolved.skillFile, 'utf8'); + const { name: skillName, description } = extractFrontmatter(resolved.skillFile); + const content = stripFrontmatter(fullContent); + const skillDirectory = path.dirname(resolved.skillFile); + + const skillHeader = `# ${skillName || skill_name} +# ${description || ''} +# Supporting tools and docs are in ${skillDirectory} +# ============================================`; + + return { + content: [ + { + type: 'text', + text: `${skillHeader}\n\n${content}` + } + ] + }; + } + + if (name === 'find_skills') { + const { superpowersSkillsDir, personalSkillsDir, projectSkillsDir } = getSkillDirectories(); + + const projectSkills = findSkillsInDir(projectSkillsDir, 'project', 3); + const personalSkills = findSkillsInDir(personalSkillsDir, 'personal', 3); + const superpowersSkills = findSkillsInDir(superpowersSkillsDir, 'superpowers', 3); + + // Priority: project > personal > superpowers + const allSkills = [...projectSkills, ...personalSkills, ...superpowersSkills]; + + if (allSkills.length === 0) { + return { + content: [ + { + type: 'text', + text: 'No skills found. Install superpowers skills or add project skills to .codebuddy/skills/' + } + ] + }; + } + + let output = 'Available skills:\n\n'; + + for (const skill of allSkills) { + let namespace; + switch (skill.sourceType) { + case 'project': + namespace = 'project:'; + break; + case 'personal': + namespace = ''; + break; + default: + namespace = 'superpowers:'; + } + const skillName = skill.name || path.basename(skill.path); + + output += `${namespace}${skillName}\n`; + if (skill.description) { + output += ` ${skill.description}\n`; + } + output += ` Directory: ${skill.path}\n\n`; + } + + return { + content: [ + { + type: 'text', + text: output + } + ] + }; + } + + if (name === 'get_bootstrap') { + const compact = args.compact || false; + const bootstrapContent = getBootstrapContent(compact); + + if (!bootstrapContent) { + throw new Error('using-superpowers skill not found'); + } + + return { + content: [ + { + type: 'text', + text: bootstrapContent + } + ] + }; + } + + throw new Error(`Unknown tool: ${name}`); +}); + +// Start the server +async function main() { + const transport = new StdioServerTransport(); + await server.connect(transport); + console.error('Superpowers MCP server running on stdio'); +} + +main().catch((error) => { + console.error('Fatal error in main():', error); + process.exit(1); +}); diff --git a/.codebuddy/mcp-server/package-lock.json b/.codebuddy/mcp-server/package-lock.json new file mode 100644 index 000000000..a372e5807 --- /dev/null +++ b/.codebuddy/mcp-server/package-lock.json @@ -0,0 +1,1129 @@ +{ + "name": "@superpowers/mcp-server-codebuddy", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@superpowers/mcp-server-codebuddy", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "superpowers-mcp-server": "index.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.2.tgz", + "integrity": "sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.7", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.11.4", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.4.tgz", + "integrity": "sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/zod": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + } + } +} diff --git a/.codebuddy/mcp-server/package.json b/.codebuddy/mcp-server/package.json new file mode 100644 index 000000000..6fd16b072 --- /dev/null +++ b/.codebuddy/mcp-server/package.json @@ -0,0 +1,29 @@ +{ + "name": "@superpowers/mcp-server-codebuddy", + "version": "1.0.0", + "description": "MCP server for CodeBuddy - provides Superpowers skills system integration", + "type": "module", + "main": "index.js", + "bin": { + "superpowers-mcp-server": "./index.js" + }, + "scripts": { + "start": "node index.js", + "test": "node test.js" + }, + "keywords": [ + "mcp", + "model-context-protocol", + "codebuddy", + "superpowers", + "skills" + ], + "author": "Jesse Vincent ", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "engines": { + "node": ">=18.0.0" + } +} diff --git a/.codebuddy/mcp-server/test.js b/.codebuddy/mcp-server/test.js new file mode 100644 index 000000000..47f839e2a --- /dev/null +++ b/.codebuddy/mcp-server/test.js @@ -0,0 +1,190 @@ +#!/usr/bin/env node + +/** + * Test script for CodeBuddy MCP server + * + * Tests core functionality without requiring MCP client connection + */ + +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import os from 'os'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// Import shared skills core +const skillsCoreModule = path.join(__dirname, '../../lib/skills-core.js'); +const { extractFrontmatter, stripFrontmatter, findSkillsInDir, resolveSkillPath } = await import( + 'file://' + skillsCoreModule +); + +console.log('Testing Superpowers MCP Server for CodeBuddy...\n'); + +// Test 1: Skills core module loading +console.log('Test 1: Loading shared skills-core module...'); +try { + console.log(' ✓ extractFrontmatter:', typeof extractFrontmatter === 'function'); + console.log(' ✓ stripFrontmatter:', typeof stripFrontmatter === 'function'); + console.log(' ✓ findSkillsInDir:', typeof findSkillsInDir === 'function'); + console.log(' ✓ resolveSkillPath:', typeof resolveSkillPath === 'function'); +} catch (error) { + console.error(' ✗ Failed to load skills-core module:', error.message); + process.exit(1); +} + +// Test 2: Skill discovery +console.log('\nTest 2: Skill discovery...'); +try { + const superpowersSkillsDir = path.join(__dirname, '../../skills'); + const skills = findSkillsInDir(superpowersSkillsDir, 'superpowers', 2); + + console.log(` ✓ Found ${skills.length} skills in superpowers directory`); + + if (skills.length === 0) { + console.error(' ✗ No skills found - check superpowers/skills/ directory'); + process.exit(1); + } + + // Show first few skills + skills.slice(0, 3).forEach((skill, index) => { + console.log(` ${index + 1}. ${skill.name || path.basename(skill.path)}`); + }); + if (skills.length > 3) { + console.log(` ... and ${skills.length - 3} more`); + } +} catch (error) { + console.error(' ✗ Skill discovery failed:', error.message); + process.exit(1); +} + +// Test 3: Skill parsing +console.log('\nTest 3: Skill parsing (frontmatter extraction)...'); +try { + const superpowersSkillsDir = path.join(__dirname, '../../skills'); + const skillFile = path.join(superpowersSkillsDir, 'using-superpowers/SKILL.md'); + + if (!fs.existsSync(skillFile)) { + console.error(' ✗ using-superpowers skill not found'); + process.exit(1); + } + + const { name, description } = extractFrontmatter(skillFile); + console.log(' ✓ Skill name:', name || '(none)'); + console.log(' ✓ Description:', description ? description.substring(0, 50) + '...' : '(none)'); + + if (!name && !description) { + console.error(' ✗ No frontmatter found in skill'); + process.exit(1); + } +} catch (error) { + console.error(' ✗ Skill parsing failed:', error.message); + process.exit(1); +} + +// Test 4: Skill resolution +console.log('\nTest 4: Skill resolution (with shadowing)...'); +try { + const superpowersSkillsDir = path.join(__dirname, '../../skills'); + const personalSkillsDir = path.join(os.homedir(), '.config', 'codebuddy', 'skills'); + + const resolved = resolveSkillPath('using-superpowers', superpowersSkillsDir, personalSkillsDir); + + if (!resolved) { + console.error(' ✗ Failed to resolve using-superpowers skill'); + process.exit(1); + } + + console.log(' ✓ Resolved using-superpowers to:', resolved.skillFile); + console.log(' ✓ Source type:', resolved.sourceType); +} catch (error) { + console.error(' ✗ Skill resolution failed:', error.message); + process.exit(1); +} + +// Test 5: Bootstrap generation +console.log('\nTest 5: Bootstrap content generation...'); +try { + const superpowersSkillsDir = path.join(__dirname, '../../skills'); + const personalSkillsDir = path.join(os.homedir(), '.config', 'codebuddy', 'skills'); + + const resolved = resolveSkillPath('using-superpowers', superpowersSkillsDir, personalSkillsDir); + const fullContent = fs.readFileSync(resolved.skillFile, 'utf8'); + const content = stripFrontmatter(fullContent); + + console.log(' ✓ Bootstrap content generated'); + console.log(' ✓ Content length:', content.length, 'characters'); + + if (content.length === 0) { + console.error(' ✗ Bootstrap content is empty'); + process.exit(1); + } +} catch (error) { + console.error(' ✗ Bootstrap generation failed:', error.message); + process.exit(1); +} + +// Test 6: Tool schemas +console.log('\nTest 6: MCP tool schemas...'); +try { + const tools = [ + { + name: 'use_skill', + description: 'Load and read a specific skill to guide your work', + required: ['skill_name'] + }, + { + name: 'find_skills', + description: 'List all available skills', + required: [] + }, + { + name: 'get_bootstrap', + description: 'Get the Superpowers bootstrap content', + required: [] + } + ]; + + tools.forEach((tool, index) => { + console.log(` ✓ Tool ${index + 1}: ${tool.name}`); + console.log(` - Required params: [${tool.required.join(', ') || 'none'}]`); + }); +} catch (error) { + console.error(' ✗ Tool schema validation failed:', error.message); + process.exit(1); +} + +// Test 7: Directory structure +console.log('\nTest 7: Directory structure...'); +try { + const requiredPaths = [ + path.join(__dirname, 'index.js'), + path.join(__dirname, 'package.json'), + path.join(__dirname, '../../lib/skills-core.js'), + path.join(__dirname, '../../skills') + ]; + + requiredPaths.forEach((filePath, index) => { + const exists = fs.existsSync(filePath); + if (exists) { + console.log(` ✓ Path ${index + 1}: ${filePath}`); + } else { + console.error(` ✗ Path ${index + 1} missing: ${filePath}`); + process.exit(1); + } + }); +} catch (error) { + console.error(' ✗ Directory structure check failed:', error.message); + process.exit(1); +} + +// All tests passed +console.log('\n' + '='.repeat(50)); +console.log('All tests passed! ✓'); +console.log('='.repeat(50)); +console.log('\nThe MCP server is ready to use with CodeBuddy.'); +console.log('\nTo test with CodeBuddy:'); +console.log('1. Configure the MCP server in CodeBuddy settings'); +console.log('2. Use find_skills tool to list available skills'); +console.log('3. Use use_skill tool to load specific skills'); +console.log('\nSee docs/README.codebuddy.md for detailed instructions.'); diff --git a/.codebuddy/settings.local.json b/.codebuddy/settings.local.json new file mode 100644 index 000000000..50b613634 --- /dev/null +++ b/.codebuddy/settings.local.json @@ -0,0 +1,44 @@ +{ + "sandbox": { + "enabled": false, + "autoAllowBashIfSandboxed": true, + "network": { + "allowedDomains": [], + "deniedDomains": [], + "allowLocalBinding": false, + "allowUnixSockets": [], + "allowAllUnixSockets": false + }, + "filesystem": { + "denyRead": [ + "~/.ssh", + "~/.aws", + "~/.gcp" + ], + "allowWrite": [ + ".", + "/dev/stdout", + "/dev/stderr", + "/dev/null", + "/dev/tty", + "/dev/dtracehelper", + "/dev/autofs_nowait", + "/tmp/codebuddy", + "/private/tmp/codebuddy", + "~/.npm/_logs", + "~/.codebuddy/debug", + "~/.codebuddy/statsig" + ], + "denyWrite": [] + }, + "excludedCommands": [], + "allowUnsandboxedCommands": true, + "enableWeakerNestedSandbox": false + }, + "permissions": { + "allow": [ + "mcp__sequential_thinking__sequentialthinking", + "mcp__filesystem__write_file" + ] + } +} \ No newline at end of file diff --git a/.codebuddy/skills/brainstorming/SKILL.md b/.codebuddy/skills/brainstorming/SKILL.md new file mode 100644 index 000000000..2fd19ba1e --- /dev/null +++ b/.codebuddy/skills/brainstorming/SKILL.md @@ -0,0 +1,54 @@ +--- +name: brainstorming +description: "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation." +--- + +# Brainstorming Ideas Into Designs + +## Overview + +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. + +## The Process + +**Understanding the idea:** +- Check out the current project state first (files, docs, recent commits) +- Ask questions one at a time to refine the idea +- 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 +- Focus on understanding: purpose, constraints, success criteria + +**Exploring approaches:** +- Propose 2-3 different approaches with trade-offs +- Present options conversationally with your recommendation and reasoning +- Lead with your recommended option and explain why + +**Presenting the design:** +- Once you believe you understand what you're building, present the design +- Break it into sections of 200-300 words +- Ask after each section whether it looks right so far +- Cover: architecture, components, data flow, error handling, testing +- Be ready to go back and clarify if something doesn't make sense + +## After the Design + +**Documentation:** +- Write the validated design to `docs/plans/YYYY-MM-DD--design.md` +- Use elements-of-style:writing-clearly-and-concisely skill if available +- Commit the design document to git + +**Implementation (if continuing):** +- Ask: "Ready to set up for implementation?" +- Use superpowers:using-git-worktrees to create isolated workspace +- Use superpowers:writing-plans to create detailed implementation plan + +## Key Principles + +- **One question at a time** - Don't overwhelm with multiple questions +- **Multiple choice preferred** - Easier to answer than open-ended when possible +- **YAGNI ruthlessly** - Remove unnecessary features from all designs +- **Explore alternatives** - Always propose 2-3 approaches before settling +- **Incremental validation** - Present design in sections, validate each +- **Be flexible** - Go back and clarify when something doesn't make sense diff --git a/.codebuddy/skills/executing-plans/SKILL.md b/.codebuddy/skills/executing-plans/SKILL.md new file mode 100644 index 000000000..ca77290c8 --- /dev/null +++ b/.codebuddy/skills/executing-plans/SKILL.md @@ -0,0 +1,76 @@ +--- +name: executing-plans +description: Use when you have a written implementation plan to execute in a separate session with review checkpoints +--- + +# Executing Plans + +## Overview + +Load plan, review critically, execute tasks in batches, report for review between batches. + +**Core principle:** Batch execution with checkpoints for architect review. + +**Announce at start:** "I'm using the executing-plans skill to implement this plan." + +## The Process + +### Step 1: Load and Review Plan +1. Read plan file +2. Review critically - identify any questions or concerns about the plan +3. If concerns: Raise them with your human partner before starting +4. If no concerns: Create TodoWrite and proceed + +### Step 2: Execute Batch +**Default: First 3 tasks** + +For each task: +1. Mark as in_progress +2. Follow each step exactly (plan has bite-sized steps) +3. Run verifications as specified +4. Mark as completed + +### Step 3: Report +When batch complete: +- Show what was implemented +- Show verification output +- Say: "Ready for feedback." + +### Step 4: Continue +Based on feedback: +- Apply changes if needed +- Execute next batch +- Repeat until complete + +### Step 5: Complete Development + +After all tasks complete and verified: +- Announce: "I'm using the finishing-a-development-branch skill to complete this work." +- **REQUIRED SUB-SKILL:** Use superpowers:finishing-a-development-branch +- Follow that skill to verify tests, present options, execute choice + +## When to Stop and Ask for Help + +**STOP executing immediately when:** +- Hit a blocker mid-batch (missing dependency, test fails, instruction unclear) +- Plan has critical gaps preventing starting +- You don't understand an instruction +- Verification fails repeatedly + +**Ask for clarification rather than guessing.** + +## When to Revisit Earlier Steps + +**Return to Review (Step 1) when:** +- Partner updates the plan based on your feedback +- Fundamental approach needs rethinking + +**Don't force through blockers** - stop and ask. + +## Remember +- Review plan critically first +- Follow plan steps exactly +- Don't skip verifications +- Reference skills when plan says to +- Between batches: just report and wait +- Stop when blocked, don't guess diff --git a/.codebuddy/skills/writing-plans/SKILL.md b/.codebuddy/skills/writing-plans/SKILL.md new file mode 100644 index 000000000..448ca3193 --- /dev/null +++ b/.codebuddy/skills/writing-plans/SKILL.md @@ -0,0 +1,116 @@ +--- +name: writing-plans +description: Use when you have a spec or requirements for a multi-step task, before touching code +--- + +# Writing Plans + +## 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. + +Assume they are a skilled developer, but know almost nothing about our toolset or problem domain. Assume they don't know good test design very well. + +**Announce at start:** "I'm using the writing-plans skill to create the implementation plan." + +**Context:** This should be run in a dedicated worktree (created by brainstorming skill). + +**Save plans to:** `docs/plans/YYYY-MM-DD-.md` + +## Bite-Sized Task Granularity + +**Each step is one action (2-5 minutes):** +- "Write the failing test" - step +- "Run it to make sure it fails" - step +- "Implement the minimal code to make the test pass" - step +- "Run the tests and make sure they pass" - step +- "Commit" - step + +## Plan Document Header + +**Every plan MUST start with this header:** + +```markdown +# [Feature Name] Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** [One sentence describing what this builds] + +**Architecture:** [2-3 sentences about approach] + +**Tech Stack:** [Key technologies/libraries] + +--- +``` + +## Task Structure + +```markdown +### Task N: [Component Name] + +**Files:** +- Create: `exact/path/to/file.py` +- Modify: `exact/path/to/existing.py:123-145` +- Test: `tests/exact/path/to/test.py` + +**Step 1: Write the failing test** + +```python +def test_specific_behavior(): + result = function(input) + assert result == expected +``` + +**Step 2: Run test to verify it fails** + +Run: `pytest tests/path/test.py::test_name -v` +Expected: FAIL with "function not defined" + +**Step 3: Write minimal implementation** + +```python +def function(input): + return expected +``` + +**Step 4: Run test to verify it passes** + +Run: `pytest tests/path/test.py::test_name -v` +Expected: PASS + +**Step 5: Commit** + +```bash +git add tests/path/test.py src/path/file.py +git commit -m "feat: add specific feature" +``` +``` + +## Remember +- Exact file paths always +- Complete code in plan (not "add validation") +- Exact commands with expected output +- Reference relevant skills with @ syntax +- DRY, YAGNI, TDD, frequent commits + +## Execution Handoff + +After saving the plan, offer execution choice: + +**"Plan complete and saved to `docs/plans/.md`. Two execution options:** + +**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration + +**2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints + +**Which approach?"** + +**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 diff --git a/.gitignore b/.gitignore index 573cae048..cfce4cfce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ .worktrees/ .private-journal/ .claude/ +.codebuddy/mcp-server/node_modules/ +.codebuddy/commands/ +package-lock.json +docs/plans/2026-01-20-superpowers-codebuddy-integration-paper-outline.md +docs/2026-01-20-superpowers-codebuddy-integration-paper.md +docs/superpowers-mcp.png diff --git a/README.md b/README.md index 0e67aefcf..d1649b13a 100644 --- a/README.md +++ b/README.md @@ -1,159 +1,188 @@ # Superpowers -Superpowers is a complete software development workflow for your coding agents, built on top of a set of composable "skills" and some initial instructions that make sure your agent uses them. +Superpowers 是为你的编程代理(coding agents)构建的完整软件开发工作流,它基于一组可组合的"技能"(skills)和一些确保你的代理正确使用这些技能的初始指令。 -## How it works +## 工作原理 -It starts from the moment you fire up your coding agent. As soon as it sees that you're building something, it *doesn't* just jump into trying to write code. Instead, it steps back and asks you what you're really trying to do. +一切都从你启动编程代理的那一刻开始。一旦它意识到你在构建某个东西,它*不会*直接跳进写代码的环节。相反,它会先停下来,问问你**真正想要做什么**。 -Once it's teased a spec out of the conversation, it shows it to you in chunks short enough to actually read and digest. +一旦它从对话中提炼出需求规格,它会以足够短的片段展示给你,让你真正能读懂并消化。 -After you've signed off on the design, your agent puts together an implementation plan that's clear enough for an enthusiastic junior engineer with poor taste, no judgement, no project context, and an aversion to testing to follow. It emphasizes true red/green TDD, YAGNI (You Aren't Gonna Need It), and DRY. +等你签署并批准设计方案后,你的代理会整理出一份清晰的实现计划——这份计划清晰到一位热情的初级工程师(品味一般、没有评判能力、不了解项目背景、还讨厌测试 😈)也能照着执行。它强调真正的红/绿 TDD、YAGNI(你以后不会需要它)和 DRY 原则。 -Next up, once you say "go", it launches a *subagent-driven-development* process, having agents work through each engineering task, inspecting and reviewing their work, and continuing forward. It's not uncommon for Claude to be able to work autonomously for a couple hours at a time without deviating from the plan you put together. +接下来,当你一声令下"出发",它就启动**子代理驱动开发**(subagent-driven-development)流程,让代理们逐个完成工程任务,检查并审查他们的工作,然后继续推进。Claude 经常能够按照你制定的计划自主工作几个小时而不跑偏! -There's a bunch more to it, but that's the core of the system. And because the skills trigger automatically, you don't need to do anything special. Your coding agent just has Superpowers. +还有很多细节,但这是系统的核心。而且因为技能是自动触发的,你不需要做任何特别的事情。你的编程代理自然就拥有了 Superpowers。 +## 赞助 -## Sponsorship +如果 Superpowers 帮你赚到了钱,而你又有意愿的话,我非常感激你能考虑[赞助我的开源工作](https://github.com/sponsors/obra)。 -If Superpowers has helped you do stuff that makes money and you are so inclined, I'd greatly appreciate it if you'd consider [sponsoring my opensource work](https://github.com/sponsors/obra). - -Thanks! +非常感谢! - Jesse +## 安装 -## Installation - -**Note:** Installation differs by platform. Claude Code has a built-in plugin system. Codex and OpenCode require manual setup. +**注意:** 安装方式因平台而异。Claude Code 有内置插件系统。Codex、OpenCode 和 CodeBuddy 需要手动设置。 -### Claude Code (via Plugin Marketplace) +### Claude Code(通过插件市场) -In Claude Code, register the marketplace first: +在 Claude Code 中,先注册市场: ```bash /plugin marketplace add obra/superpowers-marketplace ``` -Then install the plugin from this marketplace: +然后从这个市场安装插件: ```bash /plugin install superpowers@superpowers-marketplace ``` -### Verify Installation +### 验证安装 -Check that commands appear: +检查命令是否出现: ```bash /help ``` ``` -# Should see: -# /superpowers:brainstorm - Interactive design refinement -# /superpowers:write-plan - Create implementation plan -# /superpowers:execute-plan - Execute plan in batches +# 应该能看到: +# /superpowers:brainstorm - 交互式设计细化 +# /superpowers:write-plan - 创建实现计划 +# /superpowers:execute-plan - 批量执行计划 ``` ### Codex -Tell Codex: +告诉 Codex: ``` Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md ``` -**Detailed docs:** [docs/README.codex.md](docs/README.codex.md) +**详细文档:** [docs/README.codex.md](docs/README.codex.md) ### OpenCode -Tell OpenCode: +告诉 OpenCode: ``` Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.opencode/INSTALL.md ``` -**Detailed docs:** [docs/README.opencode.md](docs/README.opencode.md) +**详细文档:** [docs/README.opencode.md](docs/README.opencode.md) + +### CodeBuddy (Tencent) (包括 Internal 版本) + +CodeBuddy 通过 MCP (Model Context Protocol) 协议集成 Superpowers。 + +**快速安装:** + +克隆仓库并配置 MCP 服务器: + +```bash +mkdir -p ~/.codebuddy +git clone https://github.com/obra/superpowers.git ~/.codebuddy/superpowers +cd ~/.codebuddy/superpowers/.codebuddy/mcp-server +npm install +``` + +然后在 CodeBuddy 的 Craft 模式中配置 MCP: + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": ["~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js"], + "disabled": false, + "configSource": "user", + "timeout": 60 +} +``` + +**详细文档:** [docs/README.codebuddy.md](docs/README.codebuddy.md) -## The Basic Workflow +## 基本工作流程 -1. **brainstorming** - Activates before writing code. Refines rough ideas through questions, explores alternatives, presents design in sections for validation. Saves design document. +1. **头脑风暴(brainstorming)** - 在写代码之前激活。通过问题细化粗略的想法,探索替代方案,以章节形式展示设计以供验证。保存设计文档。 -2. **using-git-worktrees** - Activates after design approval. Creates isolated workspace on new branch, runs project setup, verifies clean test baseline. +2. **使用 Git 工作树(using-git-worktrees)** - 设计批准后激活。在新分支上创建隔离的工作空间,运行项目设置,验证干净的测试基线。 -3. **writing-plans** - Activates with approved design. Breaks work into bite-sized tasks (2-5 minutes each). Every task has exact file paths, complete code, verification steps. +3. **编写计划(writing-plans)** - 获得批准的设计后激活。将工作分解为小型任务(每个 2-5 分钟)。每个任务都有确切的文件路径、完整代码、验证步骤。 -4. **subagent-driven-development** or **executing-plans** - Activates with plan. Dispatches fresh subagent per task with two-stage review (spec compliance, then code quality), or executes in batches with human checkpoints. +4. **子代理驱动开发(subagent-driven-development)或执行计划(executing-plans)** - 有了计划后激活。为每个任务分派一个新的子代理,进行两阶段审查(先符合规格,再代码质量),或者以人工检查点的方式批量执行。 -5. **test-driven-development** - Activates during implementation. Enforces RED-GREEN-REFACTOR: write failing test, watch it fail, write minimal code, watch it pass, commit. Deletes code written before tests. +5. **测试驱动开发(test-driven-development)** - 实现过程中激活。强制执行 RED-GREEN-REFACTOR:先写失败的测试,看它失败,写最少的代码,看它通过,提交。删除测试前写的代码。 -6. **requesting-code-review** - Activates between tasks. Reviews against plan, reports issues by severity. Critical issues block progress. +6. **请求代码审查(requesting-code-review)** - 任务之间激活。对照计划审查,按严重程度报告问题。关键问题会阻塞进度。 -7. **finishing-a-development-branch** - Activates when tasks complete. Verifies tests, presents options (merge/PR/keep/discard), cleans up worktree. +7. **完成开发分支(finishing-a-development-branch)** - 任务完成后激活。验证测试,呈现选项(合并/PR/保留/丢弃),清理工作树。 -**The agent checks for relevant skills before any task.** Mandatory workflows, not suggestions. +**代理在任何任务之前都会检查相关技能。** 这是强制性的工作流程,不是建议。 -## What's Inside +## 里面有什么 -### Skills Library +### 技能库(Skills Library) -**Testing** -- **test-driven-development** - RED-GREEN-REFACTOR cycle (includes testing anti-patterns reference) +**测试** +- **test-driven-development** - RED-GREEN-REFACTOR 循环(包含测试反模式参考) -**Debugging** -- **systematic-debugging** - 4-phase root cause process (includes root-cause-tracing, defense-in-depth, condition-based-waiting techniques) -- **verification-before-completion** - Ensure it's actually fixed +**调试** +- **systematic-debugging** - 4 阶段根因过程(包含根因追踪、纵深防御、基于条件的等待技术) +- **verification-before-completion** - 确保真正修复 -**Collaboration** -- **brainstorming** - Socratic design refinement -- **writing-plans** - Detailed implementation plans -- **executing-plans** - Batch execution with checkpoints -- **dispatching-parallel-agents** - Concurrent subagent workflows -- **requesting-code-review** - Pre-review checklist -- **receiving-code-review** - Responding to feedback -- **using-git-worktrees** - Parallel development branches -- **finishing-a-development-branch** - Merge/PR decision workflow -- **subagent-driven-development** - Fast iteration with two-stage review (spec compliance, then code quality) +**协作** +- **brainstorming** - 苏格拉底式设计细化 😈 *就像苏格拉底用提问引导学生自己找到答案,这招在代码评审时也超有用!* +- **writing-plans** - 详细实现计划 +- **executing-plans** - 带检查点的批量执行 +- **dispatching-parallel-agents** - 并发子代理工作流 +- **requesting-code-review** - 预审查检查表 +- **receiving-code-review** - 响应反馈 +- **using-git-worktrees** - 并行开发分支 +- **finishing-a-development-branch** - 合并/PR 决策工作流 +- **subagent-driven-development** - 快速迭代,两阶段审查(先符合规格,再代码质量) -**Meta** -- **writing-skills** - Create new skills following best practices (includes testing methodology) -- **using-superpowers** - Introduction to the skills system +**元技能** +- **writing-skills** - 创建新技能,遵循最佳实践(包含测试方法论) +- **using-superpowers** - 技能系统介绍 -## Philosophy +## 设计理念 -- **Test-Driven Development** - Write tests first, always -- **Systematic over ad-hoc** - Process over guessing -- **Complexity reduction** - Simplicity as primary goal -- **Evidence over claims** - Verify before declaring success +- **测试驱动开发** - 始终先写测试 +- **系统化而非临时** - 过程重于猜测 +- **降低复杂度** - 简洁性是主要目标 +- **证据而非声明** - 在宣布成功之前先验证 -Read more: [Superpowers for Claude Code](https://blog.fsck.com/2025/10/09/superpowers/) +阅读更多:[Superpowers for Claude Code](https://blog.fsck.com/2025/10/09/superpowers/) -## Contributing +## 贡献 -Skills live directly in this repository. To contribute: +技能直接存储在这个仓库中。要贡献: -1. Fork the repository -2. Create a branch for your skill -3. Follow the `writing-skills` skill for creating and testing new skills -4. Submit a PR +1. Fork 仓库 +2. 为你的技能创建分支 +3. 遵循 `writing-skills` 技能来创建和测试新技能 +4. 提交 PR -See `skills/writing-skills/SKILL.md` for the complete guide. +查看 `skills/writing-skills/SKILL.md` 获取完整指南。 -## Updating +## 更新 -Skills update automatically when you update the plugin: +当你更新插件时,技能会自动更新: ```bash /plugin update superpowers ``` -## License +## 许可证 -MIT License - see LICENSE file for details +MIT 许可证 - 查看 LICENSE 文件了解详情 -## Support +## 支持 -- **Issues**: https://github.com/obra/superpowers/issues -- **Marketplace**: https://github.com/obra/superpowers-marketplace +- **问题**:https://github.com/obra/superpowers/issues +- **市场**:https://github.com/obra/superpowers-marketplace diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 5ab95451d..7cc9fa789 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,76 @@ # Superpowers Release Notes +## v4.1.0 (2025-01-19) + +### New Features + +**Added CodeBuddy support (including Internal version)** + +Superpowers now supports Tencent CodeBuddy through MCP (Model Context Protocol) integration. This is the first Chinese AI coding assistant to fully support Superpowers. + +**MCP Server Implementation:** + +- Created dedicated MCP server at `.codebuddy/mcp-server/` +- Three MCP tools provided: + - `use_skill` - Load specific skills with full content + - `find_skills` - List all available skills across directories + - `get_bootstrap` - Get superpowers bootstrap with tool mappings + +**Installation for CodeBuddy:** + +```bash +git clone https://github.com/obra/superpowers.git ~/.codebuddy/superpowers +cd ~/.codebuddy/superpowers/.codebuddy/mcp-server +npm install +``` + +Configure in CodeBuddy's MCP settings (Craft mode): +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": ["~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js"], + "disabled": false +} +``` + +**Features:** + +- **Skill Priority System**: Project → Personal → Superpowers (same as other platforms) +- **Namespace Support**: `project:`, `superpowers:`, or no prefix +- **Shared Core**: Uses `lib/skills-core.js` for code reuse with OpenCode/Codex +- **Context Compaction**: Compact bootstrap support for long sessions +- **Bootstrap Injection**: Automatic using-superpowers skill loading +- **Tool Mappings**: CodeBuddy-specific tool name translations + +**CodeBuddy Internal Version Support:** + +- Enhanced configuration options for internal deployments +- Support for `configSource: "user"` and custom timeouts +- Team knowledge base integration ready +- Multi-model support (混元, DeepSeek, GLM) compatible +- Enterprise authentication support + +**Documentation:** + +- New comprehensive guide: `docs/README.codebuddy.md` +- MCP server documentation: `.codebuddy/mcp-server/README.md` +- Test suite: `.codebuddy/mcp-server/test.js` + +**Benefits:** + +- Chinese developers can now use Superpowers in their native AI assistant +- MCP standard ensures clean integration with CodeBuddy's Craft mode +- Real-time skill loading and discovery +- Consistent skill experience across all four supported platforms + +**Technical Details:** + +The MCP server uses stdio transport and follows Model Context Protocol standards, making it compatible with any MCP-compliant tool. It shares the same core module (`lib/skills-core.js`) as OpenCode and Codex implementations, ensuring consistent skill discovery and parsing behavior across all platforms. + +--- + ## v4.0.3 (2025-12-26) ### Improvements diff --git a/docs/README.codebuddy.md b/docs/README.codebuddy.md new file mode 100644 index 000000000..7e6f777b1 --- /dev/null +++ b/docs/README.codebuddy.md @@ -0,0 +1,401 @@ +# Superpowers for CodeBuddy + +Complete guide for using Superpowers with [Tencent CodeBuddy](https://copilot.tencent.com), including support for the internal version. + +## Quick Install + +### Method 1: Using npx (Recommended for CodeBuddy Internal) + +Tell CodeBuddy in Craft mode: + +``` +Configure MCP server: +- Name: superpowers +- Type: stdio +- Command: npx +- Args: -y, github.com/binbinao/superpowers#main/.codebuddy/mcp-server + +Or download and run locally: +git clone https://github.com/binbinao/superpowers.git ~/.codebuddy/superpowers +node ~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js +``` + +### Method 2: Manual Installation + +#### Prerequisites + +- [CodeBuddy](https://copilot.tencent.com) installed (VS Code or JetBrains plugin) +- Node.js 18+ installed +- Git installed + +#### Installation Steps + +##### 1. Clone Superpowers + +```bash +mkdir -p ~/.codebuddy +git clone https://github.com/binbinao/superpowers.git ~/.codebuddy/superpowers +``` + +##### 2. Install Dependencies + +```bash +cd ~/.codebuddy/superpowers/.codebuddy/mcp-server +npm install +``` + +##### 3. Configure MCP in CodeBuddy + +**For VS Code Plugin:** + +1. Open VS Code +2. Click the CodeBuddy icon in the sidebar +3. Select "Craft" mode +4. Click "MCP" option +5. Click "Add MCP Server" or "Configure" +6. Add new server with these settings: + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": [ + "/Users/your-home/.codebuddy/superpowers/.codebuddy/mcp-server/index.js" + ], + "disabled": false +} +``` + +**For JetBrains Plugin:** + +1. Open CodeBuddy settings in your JetBrains IDE +2. Navigate to MCP configuration +3. Add new server with same settings as above + +**For Internal Version:** + +The internal version of CodeBuddy supports additional configuration options: + +```json +{ + "name": "superpowers", + "type": "stdio", + "command": "node", + "args": [ + "/Users/your-home/.codebuddy/superpowers/.codebuddy/mcp-server/index.js" + ], + "disabled": false, + "configSource": "user", + "timeout": 60 +} +``` + +##### 4. Restart CodeBuddy + +Restart CodeBuddy to load the MCP server. You should see "superpowers" in the MCP tools list. + +##### 5. Verify Installation + +Ask CodeBuddy in Craft mode: + +``` +Use the find_skills tool to list all available superpowers skills +``` + +You should see a list of available skills. + +## Usage + +### Finding Skills + +Use the `find_skills` tool in Craft mode: + +``` +Use find_skills tool to list available skills +``` + +### Loading a Skill + +Use the `use_skill` tool in Craft mode: + +``` +Use use_skill tool with skill_name: "superpowers:brainstorming" +``` + +### Getting Bootstrap + +To get the full superpowers bootstrap (recommended for new sessions): + +``` +Use get_bootstrap tool with compact: false +``` + +For compact version after context compaction: + +``` +Use get_bootstrap tool with compact: true +``` + +### Personal Skills + +Create your own skills in `~/.config/codebuddy/skills/`: + +```bash +mkdir -p ~/.config/codebuddy/skills/my-skill +``` + +Create `~/.config/codebuddy/skills/my-skill/SKILL.md`: + +```markdown +--- +name: my-skill +description: Use when [condition] - [what it does] +--- + +# My Skill + +[Your skill content here] +``` + +### Project Skills + +Create project-specific skills in your CodeBuddy project: + +```bash +# In your CodeBuddy project directory +mkdir -p .codebuddy/skills/my-project-skill +``` + +Create `.codebuddy/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 + +Skills are resolved with this priority order: + +1. **Project skills** (`.codebuddy/skills/`) - Highest priority +2. **Personal skills** (`~/.config/codebuddy/skills/`) +3. **Superpowers skills** (`~/.codebuddy/superpowers/skills/`) + +You can force resolution to a specific level: +- `project:skill-name` - Force project skill +- `skill-name` - Search project → personal → superpowers +- `superpowers:skill-name` - Force superpowers skill + +## Features + +### MCP Server Architecture + +The CodeBuddy implementation uses the Model Context Protocol (MCP) standard: + +**Location:** `~/.codebuddy/superpowers/.codebuddy/mcp-server/` + +**Components:** +- Three MCP tools: `use_skill`, `find_skills`, `get_bootstrap` +- Uses shared `lib/skills-core.js` module (also used by Codex and OpenCode) +- Automatic bootstrap on session start +- Context compaction support with compact bootstrap + +### Shared Core Module + +**Location:** `~/.codebuddy/superpowers/lib/skills-core.js` + +**Functions:** +- `extractFrontmatter()` - Parse skill metadata +- `stripFrontmatter()` - Remove metadata from content +- `findSkillsInDir()` - Recursive skill discovery +- `resolveSkillPath()` - Skill resolution with shadowing +- `checkForUpdates()` - Git update detection + +This module is shared between CodeBuddy, OpenCode, and Codex implementations for code reuse. + +### Tool Mapping + +Skills written for Claude Code are automatically adapted for CodeBuddy. The MCP server provides mapping instructions: + +- `TodoWrite` → `todo_write` +- `Task` with subagents → CodeBuddy's task system +- `Skill` tool → `use_skill` MCP tool +- File operations → Native CodeBuddy tools + +## Architecture + +### MCP Server Structure + +```javascript +// .codebuddy/mcp-server/index.js +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; + +// Exposes 3 tools: +// 1. use_skill - Load a specific skill +// 2. find_skills - List all available skills +// 3. get_bootstrap - Get superpowers bootstrap content + +// Uses shared lib/skills-core.js for skill discovery and parsing +``` + +### Configuration File (CodeBuddy Internal) + +CodeBuddy internal version supports configuring MCP via `Craft_mcp_setting.json`: + +```json +{ + "servers": { + "superpowers": { + "type": "stdio", + "command": "node", + "args": ["/path/to/.codebuddy/superpowers/.codebuddy/mcp-server/index.js"], + "disabled": false, + "configSource": "user", + "timeout": 60 + } + } +} +``` + +## Updating + +```bash +cd ~/.codebuddy/superpowers +git pull +cd .codebuddy/mcp-server +npm install # If dependencies changed +``` + +Restart CodeBuddy to load the updates. + +## Troubleshooting + +### MCP server not starting + +1. Check Node.js version: `node --version` (should be 18+) +2. Check file exists: `ls ~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js` +3. Check dependencies installed: `ls ~/.codebuddy/superpowers/.codebuddy/mcp-server/node_modules` +4. Try running manually: `node ~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js` +5. Check CodeBuddy logs for error messages + +### Skills not found + +1. Verify skills directory: `ls ~/.codebuddy/superpowers/skills` +2. Use `find_skills` tool to see what's discovered +3. Check skill structure: each skill needs a `SKILL.md` file +4. Verify MCP server is running and enabled in CodeBuddy + +### Tools not available + +1. Check MCP server is configured correctly +2. Verify CodeBuddy version supports MCP (requires recent version with MCP support) +3. Check CodeBuddy MCP settings to ensure superpowers server is enabled +4. Try restarting CodeBuddy + +### Permission errors + +1. Ensure Node.js has execute permission on the script +2. Check file permissions: `ls -la ~/.codebuddy/superpowers/.codebuddy/mcp-server/index.js` +3. If using npm install, verify ~/.npm directory is writable + +### Internal version specific issues + +For the internal version of CodeBuddy: +1. Verify `configSource: "user"` is set +2. Check if additional authentication is required +3. Verify timeout value is appropriate (default 60 seconds) +4. Check if there are specific network restrictions + +## Getting Help + +- Report issues: https://github.com/binbinao/superpowers/issues +- Main documentation: https://github.com/binbinao/superpowers +- CodeBuddy docs: https://cloud.tencent.com/document/product/1749 +- CodeBuddy MCP guide: https://cloud.tencent.com/developer/article/2526313 + +## Differences from Other Platforms + +### CodeBuddy vs Claude Code + +- **MCP Protocol**: CodeBuddy uses MCP instead of Claude's native plugin system +- **Craft Mode**: Skills work best in CodeBuddy's Craft mode +- **Tool Names**: CodeBuddy uses different tool names (todo_write vs TodoWrite) + +### CodeBuddy vs OpenCode + +- **MCP vs Plugin**: CodeBuddy uses MCP (stdio transport), OpenCode uses custom plugin system +- **Configuration**: CodeBuddy uses MCP settings, OpenCode uses opencode.json +- **Internal Version**: CodeBuddy has an internal version with extended capabilities + +### CodeBuddy vs Codex + +- **MCP vs CLI**: CodeBuddy uses MCP server, Codex uses shell scripts +- **Real-time**: MCP provides real-time tool invocation, Codex is manual +- **Richer Interface**: CodeBuddy has a GUI with Craft mode integration + +## Testing + +The implementation includes test verification. To manually test: + +```bash +cd ~/.codebuddy/superpowers +node .codebuddy/mcp-server/test.js +``` + +This will: +1. Load shared skills-core module +2. Discover all available skills +3. Test skill resolution +4. Verify bootstrap generation + +## Internal Version Features + +The internal version of CodeBuddy provides additional capabilities: + +1. **Team Knowledge Base Integration**: Skills can reference team knowledge bases +2. **Custom Agent Management**: Configure custom agents for specific workflows +3. **Multi-model Support**: Switch between different models (混元, DeepSeek, GLM) +4. **Enterprise Authentication**: SSO and enterprise account integration +5. **Advanced MCP Configuration**: More granular control over MCP servers + +To utilize these features with Superpowers: + +1. Create project skills that reference team knowledge bases +2. Configure custom agents in CodeBuddy settings to work with specific skills +3. Use MCP configuration to pass additional parameters to skills + +## Best Practices + +### For Internal CodeBuddy Users + +1. **Centralize Skills**: Use `~/.config/codebuddy/skills/` for team-wide skills +2. **Project-Specific**: Use `.codebuddy/skills/` for project-specific overrides +3. **Version Control**: Track `.codebuddy/skills/` in git for team sharing +4. **Regular Updates**: Keep superpowers updated for latest improvements +5. **Monitor Usage**: Use CodeBuddy's analytics to see which skills are most useful + +### Skill Development + +1. **Follow TDD**: Use `writing-skills` skill for creating new skills +2. **Test Locally**: Test skills in personal skills dir before promoting +3. **Document Well**: Clear descriptions help skill discovery +4. **Share with Team**: Good skills can be shared via git or team knowledge base + +## Contributing + +Skills live in this repository. To contribute: + +1. Fork the repository +2. Create a branch for your skill +3. Follow `writing-skills` skill to create and test new skills +4. Submit a PR + +See `skills/writing-skills/SKILL.md` for complete guide. diff --git a/docs/superpowers-skills-guide.md b/docs/superpowers-skills-guide.md new file mode 100644 index 000000000..b3da51a75 --- /dev/null +++ b/docs/superpowers-skills-guide.md @@ -0,0 +1,746 @@ +# Superpowers 技能学习指南 + +本文档整理了 Superpowers 项目中的所有技能(Skills),帮助你系统地学习和使用这些技能来提升 AI 辅助开发的效率和质量。 + +--- + +## 目录 + +1. [技能概述](#技能概述) +2. [核心技能分类](#核心技能分类) +3. [技能详解](#技能详解) + - [using-superpowers](#1-using-superpowers-使用技能的基础) + - [brainstorming](#2-brainstorming-头脑风暴) + - [writing-plans](#3-writing-plans-编写计划) + - [executing-plans](#4-executing-plans-执行计划) + - [subagent-driven-development](#5-subagent-driven-development-子代理驱动开发) + - [test-driven-development](#6-test-driven-development-测试驱动开发) + - [systematic-debugging](#7-systematic-debugging-系统化调试) + - [verification-before-completion](#8-verification-before-completion-完成前验证) + - [requesting-code-review](#9-requesting-code-review-请求代码审查) + - [receiving-code-review](#10-receiving-code-review-接收代码审查) + - [finishing-a-development-branch](#11-finishing-a-development-branch-完成开发分支) + - [using-git-worktrees](#12-using-git-worktrees-使用-git-worktrees) + - [dispatching-parallel-agents](#13-dispatching-parallel-agents-并行调度代理) + - [writing-skills](#14-writing-skills-编写技能) +4. [技能使用流程图](#技能使用流程图) +5. [快速参考表](#快速参考表) + +--- + +## 技能概述 + +Superpowers 是一套专为 AI 辅助开发设计的技能系统。每个技能都是经过验证的最佳实践,帮助 AI 代理(如 Claude)更有效地完成开发任务。 + +**核心原则:** +- 技能必须被主动调用,不能跳过 +- 即使只有 1% 的可能性适用,也应该调用技能检查 +- 技能定义了"如何做",用户指令定义了"做什么" + +--- + +## 核心技能分类 + +| 类别 | 技能 | 用途 | +|------|------|------| +| **流程入口** | using-superpowers | 技能系统的使用指南 | +| **设计阶段** | brainstorming | 将想法转化为设计 | +| **计划阶段** | writing-plans | 编写实现计划 | +| **执行阶段** | executing-plans, subagent-driven-development | 执行计划 | +| **质量保证** | test-driven-development, systematic-debugging, verification-before-completion | 确保代码质量 | +| **代码审查** | requesting-code-review, receiving-code-review | 代码审查流程 | +| **分支管理** | finishing-a-development-branch, using-git-worktrees | Git 工作流 | +| **并行开发** | dispatching-parallel-agents | 多任务并行处理 | +| **扩展系统** | writing-skills | 创建新技能 | + +--- + +## 技能详解 + +### 1. using-superpowers (使用技能的基础) + +**描述:** 技能系统的入门指南,定义了如何正确使用技能。 + +**核心原则:** +- 在任何响应或操作之前,先调用相关技能 +- 即使只有 1% 的可能性适用,也要调用技能 +- 如果调用后发现不适用,可以不使用 + +**技能优先级:** +1. 先使用流程技能(brainstorming, debugging)- 确定如何处理任务 +2. 再使用实现技能(frontend-design, mcp-builder)- 指导执行 + +**技能类型:** +- **严格型**(TDD, debugging):必须严格遵循 +- **灵活型**(patterns):根据上下文调整 + +**常见错误想法(红旗):** + +| 错误想法 | 现实 | +|---------|------| +| "这只是一个简单问题" | 问题也是任务,检查技能 | +| "我需要先了解更多上下文" | 技能检查在提问之前 | +| "让我先探索代码库" | 技能告诉你如何探索 | +| "这不需要正式技能" | 如果技能存在,就使用它 | + +--- + +### 2. brainstorming (头脑风暴) + +**描述:** 在任何创意工作之前必须使用 - 创建功能、构建组件、添加功能或修改行为。 + +**使用时机:** 需要将想法转化为完整设计和规格时。 + +**核心流程:** + +1. **理解想法** + - 先检查当前项目状态(文件、文档、最近提交) + - 一次问一个问题来细化想法 + - 尽可能使用选择题 + - 专注于理解:目的、约束、成功标准 + +2. **探索方案** + - 提出 2-3 个不同的方案及其权衡 + - 以对话方式呈现选项,给出推荐和理由 + - 先说推荐选项并解释原因 + +3. **呈现设计** + - 分成 200-300 字的小节 + - 每节后询问是否正确 + - 涵盖:架构、组件、数据流、错误处理、测试 + +**设计完成后:** +- 将设计写入 `docs/plans/YYYY-MM-DD--design.md` +- 提交设计文档到 git +- 如果继续实现,使用 `using-git-worktrees` 创建隔离工作区 + +**关键原则:** +- 一次一个问题 +- 尽可能用选择题 +- 严格遵循 YAGNI(不要添加不需要的功能) +- 始终探索 2-3 个备选方案 + +--- + +### 3. writing-plans (编写计划) + +**描述:** 当你有规格或需求要完成多步骤任务时,在编写代码之前使用。 + +**使用时机:** 有设计文档或需求后,在开始编码前。 + +**核心原则:** +- 假设实现者对代码库零上下文 +- 文档化他们需要知道的一切 +- 每个步骤是一个动作(2-5分钟) + +**计划文档头部格式:** +```markdown +# [功能名称] 实现计划 + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans + +**目标:** [一句话描述要构建什么] + +**架构:** [2-3句话描述方法] + +**技术栈:** [关键技术/库] + +--- +``` + +**任务结构示例:** +```markdown +### Task N: [组件名称] + +**文件:** +- Create: `exact/path/to/file.py` +- Modify: `exact/path/to/existing.py:123-145` +- Test: `tests/exact/path/to/test.py` + +**Step 1: 编写失败测试** +[代码] + +**Step 2: 运行测试验证失败** +Run: `pytest tests/path/test.py::test_name -v` +Expected: FAIL + +**Step 3: 编写最小实现** +[代码] + +**Step 4: 运行测试验证通过** +Run: `pytest tests/path/test.py::test_name -v` +Expected: PASS + +**Step 5: 提交** +```bash +git commit -m "feat: add specific feature" +``` +``` + +**执行选择:** +1. **子代理驱动**(当前会话)- 每个任务调度新子代理,任务间审查 +2. **并行会话**(单独会话)- 使用 executing-plans,批量执行 + +--- + +### 4. executing-plans (执行计划) + +**描述:** 当你有书面实现计划需要在单独会话中执行时使用。 + +**使用时机:** 有写好的计划需要执行时,带有审查检查点。 + +**核心原则:** 批量执行 + 检查点让架构师审查 + +**流程:** + +1. **加载和审查计划** + - 读取计划文件 + - 批判性审查 - 识别问题或疑虑 + - 如有疑虑:开始前与人类伙伴提出 + - 如无疑虑:创建 TodoWrite 并继续 + +2. **执行批次**(默认:前3个任务) + - 标记为进行中 + - 严格按步骤执行 + - 运行验证 + - 标记为完成 + +3. **报告** + - 显示已实现内容 + - 显示验证输出 + - 说:"Ready for feedback." + +4. **继续** + - 根据反馈应用更改 + - 执行下一批次 + +5. **完成开发** + - 使用 `finishing-a-development-branch` 技能 + +**何时停止并寻求帮助:** +- 批次中遇到阻塞 +- 计划有关键缺陷 +- 不理解指令 +- 验证反复失败 + +--- + +### 5. subagent-driven-development (子代理驱动开发) + +**描述:** 在当前会话中执行具有独立任务的实现计划时使用。 + +**使用时机:** +- 有实现计划 +- 任务大多独立 +- 想在当前会话中完成 + +**核心原则:** 每个任务使用新子代理 + 两阶段审查(规格合规 + 代码质量) + +**流程:** + +1. 读取计划,提取所有任务,创建 TodoWrite +2. 对每个任务: + - 调度实现者子代理 + - 回答子代理问题 + - 子代理实现、测试、提交、自审查 + - 调度规格审查子代理 + - 调度代码质量审查子代理 + - 标记任务完成 +3. 所有任务完成后: + - 调度最终代码审查 + - 使用 `finishing-a-development-branch` + +**与 executing-plans 的区别:** +- 同一会话(无上下文切换) +- 每个任务使用新子代理(无上下文污染) +- 两阶段审查 +- 更快迭代 + +**红旗(绝对不要):** +- 跳过审查 +- 在未解决问题时继续 +- 并行调度多个实现子代理(会冲突) +- 让子代理读取计划文件(直接提供完整文本) + +--- + +### 6. test-driven-development (测试驱动开发) + +**描述:** 在实现任何功能或修复bug时,在编写实现代码之前使用。 + +**铁律:** +``` +没有失败测试,就不能写生产代码 +``` + +**Red-Green-Refactor 循环:** + +1. **RED - 编写失败测试** + - 编写一个最小测试展示应该发生什么 + - 一个行为、清晰命名、使用真实代码 + +2. **验证 RED - 观察失败** + - 运行测试 + - 确认失败(不是错误) + - 确认失败信息符合预期 + +3. **GREEN - 最小代码** + - 编写最简单的代码让测试通过 + - 不添加额外功能 + +4. **验证 GREEN - 观察通过** + - 运行测试 + - 确认通过 + - 确认其他测试仍通过 + +5. **REFACTOR - 清理** + - 仅在绿色之后 + - 移除重复、改进命名 + - 保持测试绿色 + +**为什么顺序重要:** +- 测试后写的代码会立即通过,证明不了什么 +- 测试优先强迫你看到测试失败,证明它确实测试了某些东西 + +**常见借口与现实:** + +| 借口 | 现实 | +|------|------| +| "太简单不需要测试" | 简单代码也会出错,测试只需30秒 | +| "我之后再测试" | 立即通过的测试证明不了什么 | +| "我已经手动测试过了" | 临时测试 ≠ 系统测试 | +| "删除X小时的工作太浪费" | 沉没成本谬误,保留无法信任的代码才是技术债务 | + +--- + +### 7. systematic-debugging (系统化调试) + +**描述:** 遇到任何bug、测试失败或意外行为时,在提出修复之前使用。 + +**铁律:** +``` +没有先调查根本原因,就不能修复 +``` + +**四个阶段:** + +#### 阶段1:根本原因调查 + +1. **仔细阅读错误信息** + - 不要跳过错误或警告 + - 完整阅读堆栈跟踪 + +2. **一致性复现** + - 能可靠触发吗? + - 确切步骤是什么? + +3. **检查最近更改** + - 什么更改可能导致这个? + - Git diff,最近提交 + +4. **在多组件系统中收集证据** + - 在每个组件边界添加诊断日志 + - 运行一次收集证据 + - 分析证据确定失败组件 + +5. **追踪数据流** + - 坏值从哪里来? + - 什么调用了这个坏值? + - 继续向上追踪直到找到源头 + +#### 阶段2:模式分析 + +1. 找到工作示例 +2. 与参考比较 +3. 识别差异 +4. 理解依赖 + +#### 阶段3:假设和测试 + +1. 形成单一假设 +2. 最小化测试 +3. 验证后再继续 + +#### 阶段4:实现 + +1. 创建失败测试用例 +2. 实现单一修复 +3. 验证修复 +4. 如果3+次修复失败:质疑架构 + +**红旗(表示返回阶段1):** +- "先快速修复,之后再调查" +- "试着改变X看看是否有效" +- "我不完全理解但这可能有效" + +--- + +### 8. verification-before-completion (完成前验证) + +**描述:** 在声称工作完成、修复或通过之前,在提交或创建PR之前使用。 + +**铁律:** +``` +没有新鲜验证证据,就不能声称完成 +``` + +**门控函数:** +``` +在声称任何状态之前: + +1. 识别:什么命令证明这个声明? +2. 运行:执行完整命令(新鲜、完整) +3. 阅读:完整输出,检查退出码,计数失败 +4. 验证:输出是否确认声明? + - 如果否:用证据陈述实际状态 + - 如果是:带证据陈述声明 +5. 然后:做出声明 +``` + +**常见失败:** + +| 声明 | 需要 | 不够 | +|------|------|------| +| 测试通过 | 测试输出:0失败 | 之前的运行,"应该通过" | +| 构建成功 | 构建命令:exit 0 | lint通过,日志看起来好 | +| Bug已修复 | 测试原始症状:通过 | 代码改了,假设已修复 | +| 需求满足 | 逐行检查清单 | 测试通过 | + +**红旗:** +- 使用"应该"、"可能"、"似乎" +- 验证前表达满意("太好了!"、"完美!"、"完成!") +- 没有验证就提交/推送/PR +- 信任代理成功报告 + +--- + +### 9. requesting-code-review (请求代码审查) + +**描述:** 完成任务、实现主要功能或合并前验证工作时使用。 + +**何时请求审查:** + +**强制:** +- 子代理驱动开发中每个任务之后 +- 完成主要功能后 +- 合并到主分支前 + +**可选但有价值:** +- 卡住时(新鲜视角) +- 重构前(基线检查) +- 修复复杂bug后 + +**如何请求:** + +1. 获取 git SHAs: + ```bash + BASE_SHA=$(git rev-parse HEAD~1) + HEAD_SHA=$(git rev-parse HEAD) + ``` + +2. 调度 code-reviewer 子代理 + +3. 根据反馈行动: + - Critical 问题立即修复 + - Important 问题继续前修复 + - Minor 问题稍后处理 + - 如果审查者错了,用理由反驳 + +--- + +### 10. receiving-code-review (接收代码审查) + +**描述:** 收到代码审查反馈时,在实现建议之前使用,特别是反馈不清晰或技术上有疑问时。 + +**核心原则:** 验证后再实现。询问后再假设。技术正确性优于社交舒适。 + +**响应模式:** +``` +收到代码审查反馈时: + +1. 阅读:完整反馈,不反应 +2. 理解:用自己的话重述需求(或询问) +3. 验证:对照代码库现实检查 +4. 评估:对这个代码库技术上合理吗? +5. 响应:技术确认或有理由的反驳 +6. 实现:一次一项,每项测试 +``` + +**禁止的响应:** +- "你说得太对了!" +- "好观点!" +- "让我现在就实现"(验证前) + +**何时反驳:** +- 建议破坏现有功能 +- 审查者缺乏完整上下文 +- 违反 YAGNI +- 对此技术栈不正确 +- 与架构决策冲突 + +**确认正确反馈:** +``` +✅ "已修复。[简要描述更改了什么]" +✅ "好发现 - [具体问题]。在[位置]修复了。" +❌ "你说得对!" +❌ "谢谢!" +``` + +--- + +### 11. finishing-a-development-branch (完成开发分支) + +**描述:** 实现完成、所有测试通过、需要决定如何集成工作时使用。 + +**核心原则:** 验证测试 → 呈现选项 → 执行选择 → 清理 + +**流程:** + +1. **验证测试** + - 运行项目测试套件 + - 测试失败则停止 + +2. **确定基础分支** + ```bash + git merge-base HEAD main 2>/dev/null + ``` + +3. **呈现选项** + ``` + 实现完成。你想做什么? + + 1. 本地合并回 + 2. 推送并创建 Pull Request + 3. 保持分支现状(我稍后处理) + 4. 丢弃这个工作 + ``` + +4. **执行选择** + +5. **清理 Worktree** + - 选项1、4:移除 worktree + - 选项2、3:保留 worktree + +**选项快速参考:** + +| 选项 | 合并 | 推送 | 保留Worktree | 清理分支 | +|------|------|------|--------------|----------| +| 1. 本地合并 | ✓ | - | - | ✓ | +| 2. 创建PR | - | ✓ | ✓ | - | +| 3. 保持现状 | - | - | ✓ | - | +| 4. 丢弃 | - | - | - | ✓ (force) | + +--- + +### 12. using-git-worktrees (使用 Git Worktrees) + +**描述:** 开始需要与当前工作区隔离的功能工作时,或执行实现计划前使用。 + +**核心原则:** 系统化目录选择 + 安全验证 = 可靠隔离 + +**目录选择优先级:** + +1. 检查现有目录 + ```bash + ls -d .worktrees 2>/dev/null + ls -d worktrees 2>/dev/null + ``` + +2. 检查 CLAUDE.md 中的偏好 + +3. 询问用户 + +**安全验证:** +- 对于项目本地目录,必须验证目录被 gitignore +- 如果未被忽略,添加到 .gitignore 并提交 + +**创建步骤:** + +1. 检测项目名称 +2. 创建 Worktree + ```bash + git worktree add "$path" -b "$BRANCH_NAME" + ``` +3. 运行项目设置(npm install 等) +4. 验证干净基线(运行测试) +5. 报告位置 + +**常见错误:** +- 跳过忽略验证 +- 假设目录位置 +- 测试失败时继续 +- 硬编码设置命令 + +--- + +### 13. dispatching-parallel-agents (并行调度代理) + +**描述:** 面对2+个独立任务,可以不共享状态或无顺序依赖时使用。 + +**核心原则:** 每个独立问题域调度一个代理,让它们并发工作。 + +**何时使用:** +- 3+ 个测试文件因不同根因失败 +- 多个子系统独立损坏 +- 每个问题可以不需要其他问题的上下文理解 +- 调查之间无共享状态 + +**何时不使用:** +- 失败相关(修一个可能修复其他) +- 需要理解完整系统状态 +- 代理会相互干扰 + +**模式:** + +1. **识别独立域** + - 按什么损坏分组失败 + +2. **创建聚焦的代理任务** + - 具体范围:一个测试文件或子系统 + - 清晰目标:让这些测试通过 + - 约束:不改变其他代码 + - 预期输出:发现和修复的摘要 + +3. **并行调度** + +4. **审查和集成** + - 阅读每个摘要 + - 验证修复不冲突 + - 运行完整测试套件 + +**代理提示结构:** +```markdown +修复 src/agents/agent-tool-abort.test.ts 中的3个失败测试: + +1. "should abort tool..." - 期望消息中有 'interrupted at' +2. "should handle mixed..." - 快速工具被中止而不是完成 +3. "should properly track..." - 期望3个结果但得到0 + +这些是时序/竞态条件问题。你的任务: + +1. 读取测试文件理解每个测试验证什么 +2. 识别根因 - 时序问题还是实际bug? +3. 修复... + +返回:发现和修复内容的摘要。 +``` + +--- + +### 14. writing-skills (编写技能) + +**描述:** 创建新技能、编辑现有技能或验证技能在部署前有效时使用。 + +**核心原则:** 编写技能 IS 测试驱动开发应用于流程文档。 + +**技能是什么:** +- 可重用技术、模式、工具、参考指南 +- **不是**:关于你如何解决某个问题的叙述 + +**TDD 映射:** + +| TDD 概念 | 技能创建 | +|---------|---------| +| 测试用例 | 带子代理的压力场景 | +| 生产代码 | 技能文档 (SKILL.md) | +| 测试失败 (RED) | 代理在无技能时违反规则 | +| 测试通过 (GREEN) | 代理在有技能时遵守 | +| 重构 | 关闭漏洞同时保持合规 | + +**SKILL.md 结构:** +```markdown +--- +name: skill-name-with-hyphens +description: Use when [specific triggering conditions] +--- + +# 技能名称 + +## Overview +什么是这个?1-2句核心原则。 + +## When to Use +症状和用例的项目符号列表 + +## Core Pattern +前后代码比较 + +## Quick Reference +扫描常见操作的表格 + +## Common Mistakes +什么出错 + 修复 +``` + +**描述字段关键点:** +- 以 "Use when..." 开始 +- 只描述触发条件 +- **绝不**总结技能的流程或工作流 + +**铁律:** +``` +没有失败测试,就不能写技能 +``` + +--- + +## 技能使用流程图 + +``` + ┌──────────────────┐ + │ 收到用户消息 │ + └────────┬─────────┘ + │ + ▼ + ┌──────────────────┐ + │ 可能有技能适用? │ + └────────┬─────────┘ + │ + ┌──────────────┴──────────────┐ + │ 是(即使1%) │ 否 + ▼ ▼ + ┌─────────────────┐ ┌─────────────────┐ + │ 调用技能工具 │ │ 直接响应 │ + └────────┬────────┘ └─────────────────┘ + │ + ▼ + ┌─────────────────┐ + │ 宣布使用技能 │ + └────────┬────────┘ + │ + ▼ + ┌─────────────────┐ + │ 严格遵循技能 │ + └─────────────────┘ +``` + +--- + +## 快速参考表 + +| 我想要... | 使用技能 | +|----------|---------| +| 将想法变成设计 | brainstorming | +| 创建实现计划 | writing-plans | +| 执行计划(分开会话) | executing-plans | +| 执行计划(当前会话) | subagent-driven-development | +| 写代码 | test-driven-development | +| 调试问题 | systematic-debugging | +| 确认工作完成 | verification-before-completion | +| 请求代码审查 | requesting-code-review | +| 处理审查反馈 | receiving-code-review | +| 完成分支工作 | finishing-a-development-branch | +| 创建隔离工作区 | using-git-worktrees | +| 并行解决多个问题 | dispatching-parallel-agents | +| 创建新技能 | writing-skills | + +--- + +## 学习建议 + +1. **从 using-superpowers 开始** - 理解技能系统的基本原则 +2. **掌握核心流程** - brainstorming → writing-plans → executing-plans +3. **内化质量技能** - test-driven-development, verification-before-completion +4. **按需学习其他技能** - 遇到具体场景时深入学习 + +**记住:** 技能是经过验证的最佳实践,即使感觉"可能不需要",也应该先调用检查。