Jelajahi Sumber

Drop installer script and AGENTS.md gatekeeper

Testing showed native skill discovery works without the AGENTS.md
gatekeeper — using-superpowers bootstraps itself via SKILL.md
frontmatter. Install is now just clone + symlink, driven by
INSTALL.md. No Node.js dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drew Ritter 7 bulan lalu
induk
melakukan
6a07692da1
3 mengubah file dengan 29 tambahan dan 243 penghapusan
  1. 16 14
      .codex/INSTALL.md
  2. 0 199
      .codex/install-codex.mjs
  3. 13 30
      docs/README.codex.md

+ 16 - 14
.codex/INSTALL.md

@@ -1,33 +1,35 @@
 # Installing Superpowers for Codex
 
-Quick setup to enable superpowers skills in Codex. The installer links your skills into Codex's native discovery path so they load automatically.
+Enable superpowers skills in Codex via native skill discovery. Just clone and symlink.
 
 ## Prerequisites
 
-- [Node.js](https://nodejs.org/) (v16+)
 - Git
 
 ## Installation
 
-1. **Clone superpowers repository**:
+1. **Clone the superpowers repository:**
    ```bash
    git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
    ```
 
-2. **Run the installer**:
+2. **Create the skills symlink:**
    ```bash
-   node ~/.codex/superpowers/.codex/install-codex.mjs
+   mkdir -p ~/.agents/skills
+   ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers
    ```
 
-3. **Restart Codex** (quit and relaunch the CLI) to discover the skills.
+   **Windows (PowerShell):**
+   ```powershell
+   New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills"
+   cmd /c mklink /J "$env:USERPROFILE\.agents\skills\superpowers" "$env:USERPROFILE\.codex\superpowers\skills"
+   ```
 
-**Windows:** The installer creates a junction (`mklink /J`), which works without Developer Mode.
+3. **Restart Codex** (quit and relaunch the CLI) to discover the skills.
 
-## What the installer does
+## Migrating from old bootstrap
 
-- Links `~/.agents/skills/superpowers` → `~/.codex/superpowers/skills` (symlink on macOS/Linux, junction on Windows)
-- Adds a gatekeeper block to `~/.codex/AGENTS.md` that tells Codex to use superpowers skills
-- If you had the old bootstrap setup, it removes it automatically
+If your `~/.codex/AGENTS.md` contains a superpowers block that references `superpowers-codex bootstrap`, remove that block — it's no longer needed. Native skill discovery replaces the old bootstrap system.
 
 ## Verify
 
@@ -35,7 +37,7 @@ Quick setup to enable superpowers skills in Codex. The installer links your skil
 ls -la ~/.agents/skills/superpowers
 ```
 
-You should see a symlink (or junction) pointing to your superpowers skills directory.
+You should see a symlink (or junction on Windows) pointing to your superpowers skills directory.
 
 ## Updating
 
@@ -43,7 +45,7 @@ You should see a symlink (or junction) pointing to your superpowers skills direc
 cd ~/.codex/superpowers && git pull
 ```
 
-Skills update instantly through the link.
+Skills update instantly through the symlink.
 
 ## Uninstalling
 
@@ -51,4 +53,4 @@ Skills update instantly through the link.
 rm ~/.agents/skills/superpowers
 ```
 
-Then remove the block between `<!-- superpowers:begin -->` and `<!-- superpowers:end -->` from `~/.codex/AGENTS.md`. Optionally delete the clone: `rm -rf ~/.codex/superpowers`.
+Optionally delete the clone: `rm -rf ~/.codex/superpowers`.

+ 0 - 199
.codex/install-codex.mjs

@@ -1,199 +0,0 @@
-#!/usr/bin/env node
-
-// Minimal installer for Superpowers native Codex skill discovery.
-// Creates a symlink from ~/.agents/skills/superpowers → repo skills/
-// and updates ~/.codex/AGENTS.md with a gatekeeper block.
-
-import { existsSync, readFileSync, writeFileSync, mkdirSync, symlinkSync, lstatSync, readlinkSync, unlinkSync } from 'fs';
-import { join, resolve, dirname } from 'path';
-import { fileURLToPath } from 'url';
-import { homedir, platform } from 'os';
-import { execSync } from 'child_process';
-
-const home = homedir();
-const isWindows = platform() === 'win32';
-
-// Paths
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const repoSkillsDir = resolve(__dirname, '..', 'skills');
-const agentsSkillsDir = join(home, '.agents', 'skills');
-const symlinkPath = join(agentsSkillsDir, 'superpowers');
-const agentsMdPath = join(home, '.codex', 'AGENTS.md');
-
-const GATEKEEPER_BEGIN = '<!-- superpowers:begin -->';
-const GATEKEEPER_END = '<!-- superpowers:end -->';
-
-const GATEKEEPER_BLOCK = `${GATEKEEPER_BEGIN}
-## Superpowers
-
-**MANDATORY: Invoke $using-superpowers before proceeding with ANY task.**
-
-IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT.
-
-### Tool Mappings for Codex
-- \`TodoWrite\` → \`update_plan\`
-- \`Task\`/\`Subagent\` → \`spawn_agent\` + \`wait\` (or sequential if collab disabled)
-- \`Skill\` tool → native \`$skill-name\` mention
-- \`Read\`, \`Write\`, \`Edit\`, \`Bash\` → use your native equivalents
-${GATEKEEPER_END}`;
-
-// --- Symlink creation ---
-
-function createSymlink() {
-  // Ensure parent dir exists
-  mkdirSync(agentsSkillsDir, { recursive: true });
-
-  // Check if target already exists
-  if (existsSync(symlinkPath)) {
-    try {
-      const stat = lstatSync(symlinkPath);
-      if (stat.isSymbolicLink()) {
-        const target = readlinkSync(symlinkPath);
-        if (resolve(target) === resolve(repoSkillsDir)) {
-          console.log(`✓ Symlink already exists: ${symlinkPath} → ${repoSkillsDir}`);
-          return;
-        }
-        console.log(`! Existing symlink points to ${target}, updating to ${repoSkillsDir}`);
-        unlinkSync(symlinkPath);
-      } else {
-        console.error(`✗ ${symlinkPath} already exists and is not a symlink.`);
-        console.error(`  Remove it manually and re-run the installer.`);
-        process.exit(1);
-      }
-    } catch (err) {
-      console.error(`✗ Cannot inspect ${symlinkPath}: ${err.message}`);
-      process.exit(1);
-    }
-  }
-
-  // Create the link (symlink on macOS/Linux, junction on Windows)
-  const linkType = isWindows ? 'junction' : 'dir';
-  const linkLabel = isWindows ? 'junction' : 'symlink';
-  try {
-    symlinkSync(repoSkillsDir, symlinkPath, linkType);
-    console.log(`✓ Created ${linkLabel}: ${symlinkPath} → ${repoSkillsDir}`);
-  } catch (err) {
-    if (isWindows) {
-      // Node API failed on Windows — try junction via cmd.exe
-      try {
-        execSync(`cmd /c mklink /J "${symlinkPath}" "${repoSkillsDir}"`, { stdio: 'pipe' });
-        console.log(`✓ Created junction: ${symlinkPath} → ${repoSkillsDir}`);
-      } catch (junctionErr) {
-        console.error(`✗ Failed to create junction: ${junctionErr.message}`);
-        console.error(`  Try running PowerShell as administrator.`);
-        process.exit(1);
-      }
-    } else {
-      console.error(`✗ Failed to create symlink: ${err.message}`);
-      process.exit(1);
-    }
-  }
-}
-
-// --- AGENTS.md update ---
-
-// Patterns that identify the old bootstrap block
-const OLD_BLOCK_PATTERNS = [
-  'superpowers-codex bootstrap',
-  'superpowers-codex use-skill',
-  'superpowers-codex find-skills',
-];
-
-function removeOldBootstrapBlock(content) {
-  const lines = content.split('\n');
-  const result = [];
-  let inOldBlock = false;
-
-  for (let i = 0; i < lines.length; i++) {
-    const line = lines[i];
-
-    // Detect start of old block by its section header
-    if (!inOldBlock && line.startsWith('## ') && line.includes('Superpowers')) {
-      // Check if this section contains old bootstrap patterns (look ahead)
-      const sectionEnd = lines.findIndex((l, j) => j > i && l.startsWith('## ') && !l.includes('Superpowers'));
-      const sectionLines = lines.slice(i, sectionEnd === -1 ? lines.length : sectionEnd);
-      const hasOldPatterns = sectionLines.some(l => OLD_BLOCK_PATTERNS.some(p => l.includes(p)));
-      if (hasOldPatterns) {
-        inOldBlock = true;
-        // Also remove leading blank lines before the header
-        while (result.length > 0 && result[result.length - 1].trim() === '') {
-          result.pop();
-        }
-        continue;
-      }
-    }
-
-    if (inOldBlock) {
-      // End of old block: next non-Superpowers section header
-      if (line.startsWith('## ') && !line.includes('Superpowers')) {
-        inOldBlock = false;
-        result.push(line);
-        continue;
-      }
-      // Skip this line (part of old block)
-      continue;
-    }
-
-    result.push(line);
-  }
-
-  return result.join('\n');
-}
-
-function updateAgentsMd() {
-  let content = '';
-
-  if (existsSync(agentsMdPath)) {
-    content = readFileSync(agentsMdPath, 'utf8');
-
-    // Check if gatekeeper already present
-    if (content.includes(GATEKEEPER_BEGIN)) {
-      // Replace existing gatekeeper block
-      const beginIdx = content.indexOf(GATEKEEPER_BEGIN);
-      const endIdx = content.indexOf(GATEKEEPER_END);
-      if (endIdx > beginIdx) {
-        content = content.slice(0, beginIdx) + GATEKEEPER_BLOCK + content.slice(endIdx + GATEKEEPER_END.length);
-        writeFileSync(agentsMdPath, content, 'utf8');
-        console.log(`✓ Updated existing gatekeeper block in ${agentsMdPath}`);
-        return;
-      }
-    }
-
-    // Remove old bootstrap block if present
-    const hasOldBlock = OLD_BLOCK_PATTERNS.some(p => content.includes(p));
-    if (hasOldBlock) {
-      content = removeOldBootstrapBlock(content);
-      console.log(`  Removed old bootstrap block from AGENTS.md`);
-    }
-  } else {
-    // Ensure directory exists
-    mkdirSync(join(home, '.codex'), { recursive: true });
-  }
-
-  // Append gatekeeper block
-  const separator = content.length > 0 && !content.endsWith('\n\n') ? (content.endsWith('\n') ? '\n' : '\n\n') : '';
-  content = content + separator + GATEKEEPER_BLOCK + '\n';
-  writeFileSync(agentsMdPath, content, 'utf8');
-  console.log(`✓ Added gatekeeper block to ${agentsMdPath}`);
-}
-
-// --- Main ---
-
-console.log('Superpowers — Codex Native Skills Installer');
-console.log('');
-
-if (!existsSync(repoSkillsDir)) {
-  console.error(`✗ Skills directory not found: ${repoSkillsDir}`);
-  console.error(`  Are you running this from the superpowers repo?`);
-  process.exit(1);
-}
-
-createSymlink();
-updateAgentsMd();
-
-console.log('');
-console.log('Done! Restart Codex to discover superpowers skills natively.');
-console.log('');
-console.log('To update:  cd ~/.codex/superpowers && git pull');
-console.log('To remove:  rm ~/.agents/skills/superpowers');
-console.log('            Then remove the superpowers block from ~/.codex/AGENTS.md');

+ 13 - 30
docs/README.codex.md

@@ -15,7 +15,7 @@ Fetch and follow instructions from https://raw.githubusercontent.com/obra/superp
 ### Prerequisites
 
 - OpenAI Codex CLI
-- Node.js (for the installer script)
+- Git
 
 ### Steps
 
@@ -24,18 +24,22 @@ Fetch and follow instructions from https://raw.githubusercontent.com/obra/superp
    git clone https://github.com/obra/superpowers.git ~/.codex/superpowers
    ```
 
-2. Run the installer:
+2. Create the skills symlink:
    ```bash
-   node ~/.codex/superpowers/.codex/install-codex.mjs
+   mkdir -p ~/.agents/skills
+   ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers
    ```
 
 3. Restart Codex.
 
-The installer links `~/.agents/skills/superpowers` to the repo's `skills/` directory (symlink on macOS/Linux, junction on Windows) and adds a gatekeeper block to `~/.codex/AGENTS.md`. Existing users with the old bootstrap setup are migrated automatically.
-
 ### Windows
 
-The installer creates a junction (`mklink /J`) on Windows, which works without Developer Mode. On macOS/Linux it creates a standard symlink. Both work for Codex skill discovery.
+Use a junction instead of a symlink (works without Developer Mode):
+
+```powershell
+New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills"
+cmd /c mklink /J "$env:USERPROFILE\.agents\skills\superpowers" "$env:USERPROFILE\.codex\superpowers\skills"
+```
 
 ## How It Works
 
@@ -45,7 +49,7 @@ Codex has native skill discovery — it scans `~/.agents/skills/` at startup, pa
 ~/.agents/skills/superpowers/ → ~/.codex/superpowers/skills/
 ```
 
-A small gatekeeper block in `~/.codex/AGENTS.md` ensures Codex invokes `$using-superpowers` at session start, which enforces skill usage discipline across turns.
+The `using-superpowers` skill is discovered automatically and enforces skill usage discipline — no additional configuration needed.
 
 ## Usage
 
@@ -54,19 +58,6 @@ Skills are discovered automatically. Codex activates them when:
 - The task matches a skill's description
 - The `using-superpowers` skill directs Codex to use one
 
-### Tool Mappings
-
-Skills written for Claude Code reference tools that have Codex equivalents:
-
-| Claude Code | Codex |
-|-------------|-------|
-| `TodoWrite` | `update_plan` |
-| `Task`/`Subagent` | `spawn_agent` + `wait` (or sequential if collab disabled) |
-| `Skill` tool | Native `$skill-name` mention |
-| `Read`, `Write`, `Edit`, `Bash` | Native equivalents |
-
-These mappings are included in the AGENTS.md gatekeeper block.
-
 ### Personal Skills
 
 Create your own skills in `~/.agents/skills/`:
@@ -104,7 +95,7 @@ Skills update instantly through the symlink.
 rm ~/.agents/skills/superpowers
 ```
 
-Then remove the block between `<!-- superpowers:begin -->` and `<!-- superpowers:end -->` from `~/.codex/AGENTS.md`.
+Optionally delete the clone: `rm -rf ~/.codex/superpowers`.
 
 ## Troubleshooting
 
@@ -116,15 +107,7 @@ Then remove the block between `<!-- superpowers:begin -->` and `<!-- superpowers
 
 ### Windows junction issues
 
-The installer creates junctions on Windows, which normally work without special permissions. If junction creation fails, try running PowerShell as administrator.
-
-### Node.js not found
-
-The installer requires Node.js. Verify:
-
-```bash
-node --version
-```
+Junctions normally work without special permissions. If creation fails, try running PowerShell as administrator.
 
 ## Getting Help