playbook/superpowers/docs/plans/2025-11-22-opencode-support...

8.6 KiB

OpenCode Support Design

Date: 2025-11-22 Author: Bot & Jesse Status: Design Complete, Awaiting Implementation

Overview

Add full superpowers support for OpenCode.ai using a native OpenCode plugin architecture that shares core functionality with the existing Codex implementation.

Background

OpenCode.ai is a coding agent similar to Claude Code and Codex. Previous attempts to port superpowers to OpenCode (PR #93, PR #116) used file-copying approaches. This design takes a different approach: building a native OpenCode plugin using their JavaScript/TypeScript plugin system while sharing code with the Codex implementation.

Key Differences Between Platforms

  • Claude Code: Native Anthropic plugin system + file-based skills
  • Codex: No plugin system → bootstrap markdown + CLI script
  • OpenCode: JavaScript/TypeScript plugins with event hooks and custom tools API

OpenCode's Agent System

  • Primary agents: Build (default, full access) and Plan (restricted, read-only)
  • Subagents: General (research, searching, multi-step tasks)
  • Invocation: Automatic dispatch by primary agents OR manual @mention syntax
  • Configuration: Custom agents in opencode.json or ~/.config/opencode/agent/

Architecture

High-Level Structure

  1. Shared Core Module (lib/skills-core.js)

    • Common skill discovery and parsing logic
    • Used by both Codex and OpenCode implementations
  2. Platform-Specific Wrappers

    • Codex: CLI script (.codex/superpowers-codex)
    • OpenCode: Plugin module (.opencode/plugin/superpowers.js)
  3. Skill Directories

    • Core: ~/.config/opencode/superpowers/skills/ (or installed location)
    • Personal: ~/.config/opencode/skills/ (shadows core skills)

Code Reuse Strategy

Extract common functionality from .codex/superpowers-codex into shared module:

// lib/skills-core.js
module.exports = {
  extractFrontmatter(filePath),      // Parse name + description from YAML
  findSkillsInDir(dir, maxDepth),    // Recursive SKILL.md discovery
  findAllSkills(dirs),                // Scan multiple directories
  resolveSkillPath(skillName, dirs), // Handle shadowing (personal > core)
  checkForUpdates(repoDir)           // Git fetch/status check
};

Skill Frontmatter Format

Current format (no when_to_use field):

---
name: skill-name
description: Use when [condition] - [what it does]; [additional context]
---

OpenCode Plugin Implementation

Custom Tools

Tool 1: use_skill

Loads a specific skill's content into the conversation (equivalent to Claude's Skill tool).

{
  name: 'use_skill',
  description: 'Load and read a specific skill to guide your work',
  schema: z.object({
    skill_name: z.string().describe('Name of skill (e.g., "superpowers:brainstorming")')
  }),
  execute: async ({ skill_name }) => {
    const { skillPath, content, frontmatter } = resolveAndReadSkill(skill_name);
    const skillDir = path.dirname(skillPath);

    return `# ${frontmatter.name}
# ${frontmatter.description}
# Supporting tools and docs are in ${skillDir}
# ============================================

${content}`;
  }
}

Tool 2: find_skills

Lists all available skills with metadata.

{
  name: 'find_skills',
  description: 'List all available skills',
  schema: z.object({}),
  execute: async () => {
    const skills = discoverAllSkills();
    return skills.map(s =>
      `${s.namespace}:${s.name}
  ${s.description}
  Directory: ${s.directory}
`).join('\n');
  }
}

Session Startup Hook

When a new session starts (session.started event):

  1. Inject using-superpowers content

    • Full content of the using-superpowers skill
    • Establishes mandatory workflows
  2. Run find_skills automatically

    • Display full list of available skills upfront
    • Include skill directories for each
  3. Inject tool mapping instructions

    **Tool Mapping for OpenCode:**
    When skills reference tools you don't have, substitute:
    - `TodoWrite``update_plan`
    - `Task` with subagents → Use OpenCode subagent system (@mention)
    - `Skill` tool → `use_skill` custom tool
    - Read, Write, Edit, Bash → Your native equivalents
    
    **Skill directories contain:**
    - Supporting scripts (run with bash)
    - Additional documentation (read with read tool)
    - Utilities specific to that skill
    
  4. Check for updates (non-blocking)

    • Quick git fetch with timeout
    • Notify if updates available

Plugin Structure

// .opencode/plugin/superpowers.js
const skillsCore = require('../../lib/skills-core');
const path = require('path');
const fs = require('fs');
const { z } = require('zod');

export const SuperpowersPlugin = async ({ client, directory, $ }) => {
  const superpowersDir = path.join(process.env.HOME, '.config/opencode/superpowers');
  const personalDir = path.join(process.env.HOME, '.config/opencode/skills');

  return {
    'session.started': async () => {
      const usingSuperpowers = await readSkill('using-superpowers');
      const skillsList = await findAllSkills();
      const toolMapping = getToolMappingInstructions();

      return {
        context: `${usingSuperpowers}\n\n${skillsList}\n\n${toolMapping}`
      };
    },

    tools: [
      {
        name: 'use_skill',
        description: 'Load and read a specific skill',
        schema: z.object({
          skill_name: z.string()
        }),
        execute: async ({ skill_name }) => {
          // Implementation using skillsCore
        }
      },
      {
        name: 'find_skills',
        description: 'List all available skills',
        schema: z.object({}),
        execute: async () => {
          // Implementation using skillsCore
        }
      }
    ]
  };
};

File Structure

superpowers/
├── lib/
│   └── skills-core.js           # NEW: Shared skill logic
├── .codex/
│   ├── superpowers-codex        # UPDATED: Use skills-core
│   ├── superpowers-bootstrap.md
│   └── INSTALL.md
├── .opencode/
│   ├── plugin/
│   │   └── superpowers.js       # NEW: OpenCode plugin
│   └── INSTALL.md               # NEW: Installation guide
└── skills/                       # Unchanged

Implementation Plan

Phase 1: Refactor Shared Core

  1. Create lib/skills-core.js

    • Extract frontmatter parsing from .codex/superpowers-codex
    • Extract skill discovery logic
    • Extract path resolution (with shadowing)
    • Update to use only name and description (no when_to_use)
  2. Update .codex/superpowers-codex to use shared core

    • Import from ../lib/skills-core.js
    • Remove duplicated code
    • Keep CLI wrapper logic
  3. Test Codex implementation still works

    • Verify bootstrap command
    • Verify use-skill command
    • Verify find-skills command

Phase 2: Build OpenCode Plugin

  1. Create .opencode/plugin/superpowers.js

    • Import shared core from ../../lib/skills-core.js
    • Implement plugin function
    • Define custom tools (use_skill, find_skills)
    • Implement session.started hook
  2. Create .opencode/INSTALL.md

    • Installation instructions
    • Directory setup
    • Configuration guidance
  3. Test OpenCode implementation

    • Verify session startup bootstrap
    • Verify use_skill tool works
    • Verify find_skills tool works
    • Verify skill directories are accessible

Phase 3: Documentation & Polish

  1. Update README with OpenCode support
  2. Add OpenCode installation to main docs
  3. Update RELEASE-NOTES
  4. Test both Codex and OpenCode work correctly

Next Steps

  1. Create isolated workspace (using git worktrees)

    • Branch: feature/opencode-support
  2. Follow TDD where applicable

    • Test shared core functions
    • Test skill discovery and parsing
    • Integration tests for both platforms
  3. Incremental implementation

    • Phase 1: Refactor shared core + update Codex
    • Verify Codex still works before moving on
    • Phase 2: Build OpenCode plugin
    • Phase 3: Documentation and polish
  4. Testing strategy

    • Manual testing with real OpenCode installation
    • Verify skill loading, directories, scripts work
    • Test both Codex and OpenCode side-by-side
    • Verify tool mappings work correctly
  5. PR and merge

    • Create PR with complete implementation
    • Test in clean environment
    • Merge to main

Benefits

  • Code reuse: Single source of truth for skill discovery/parsing
  • Maintainability: Bug fixes apply to both platforms
  • Extensibility: Easy to add future platforms (Cursor, Windsurf, etc.)
  • Native integration: Uses OpenCode's plugin system properly
  • Consistency: Same skill experience across all platforms