EveryInc/compound-engineering-plugin · error · Error

Cleanup currently supports only the compound-engineering…

Error message

Cleanup currently supports only the compound-engineering plugin.

What it means

The `cleanup` command removes installed compound-engineering artifacts from agent homes, but its logic (targets, stale-artifact registries) is written specifically for the compound-engineering plugin. After loading the plugin at the resolved path, `run` checks `plugin.manifest.name` and throws this error if it is anything else. This guards against running removal routines designed for one plugin against another plugin's installed files.

Solutions

  1. Run cleanup against the actual compound-engineering plugin (omit --plugin or pass "compound-engineering").
  2. If using a local checkout, verify its .claude-plugin/plugin.json declares "name": "compound-engineering"; fix the name or use the official plugin.
  3. If you need to remove a different plugin, remove its artifacts manually (or with the plugin's own tooling) instead of using this command.

Example fix

// before
bun run src/index.ts cleanup --plugin ./my-fork
// Error: Cleanup currently supports only the compound-engineering plugin.

// after
bun run src/index.ts cleanup --plugin compound-engineering
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync, existsSync } from "node:fs"
const manifestPath = pluginPath + "/.claude-plugin/plugin.json"
if (!existsSync(manifestPath)) throw new Error(`No plugin manifest at ${manifestPath}`)
const name = JSON.parse(readFileSync(manifestPath, "utf8")).manifest?.name ?? JSON.parse(readFileSync(manifestPath, "utf8")).name
if (name !== "compound-engineering") {
  console.warn(`Skipping cleanup: ${pluginPath} is '${name}', not compound-engineering`)
}

Type guard

function isCompoundEngineeringManifest(m: unknown): m is { name: "compound-engineering" } {
  return typeof m === "object" && m !== null && (m as any).name === "compound-engineering"
}

Try / catch

try {
  await cleanupCommand.run({ args })
} catch (e) {
  if (e instanceof Error && e.message.includes("only the compound-engineering plugin")) {
    console.error(`Wrong plugin for cleanup: ${args.plugin}. Use the compound-engineering plugin.`)
  } else throw e
}

Prevention

When it happens

Trigger: Running `cleanup` (with no --plugin, defaults to "compound-engineering") where resolveCleanupPluginPath resolves to a plugin whose .claude-plugin/plugin.json has a different `name` — e.g. passing `--plugin ./some-other-plugin` pointing at a valid but differently-named plugin directory.

Common situations: A developer points --plugin at a checkout of a fork or a different plugin to try to clean it up; a repo was renamed so the manifest name no longer matches; someone copies the cleanup workflow to clean another Claude plugin's installs.

Related errors


AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31). Data as JSON: /api/errors/3032123fa206d08b. Report an issue: GitHub.

Appendix: source

Thrown at src/commands/cleanup.ts:110

      alias: "qwen-home",
      description: "Qwen root to clean for legacy Bun installs (default: ~/.qwen)",
    },
    windsurfHome: {
      type: "string",
      alias: "windsurf-home",
      description: "Deprecated Windsurf root to clean (default: ~/.codeium/windsurf)",
    },
    agentsHome: {
      type: "string",
      alias: "agents-home",
      description: "Shared .agents root to clean for shadowing skills (default: ~/.agents)",
    },
  },
  async run({ args }) {
    const pluginPath = await resolveCleanupPluginPath(args.plugin ? String(args.plugin) : "compound-engineering")
    const plugin = await loadClaudePlugin(pluginPath)
    if (plugin.manifest.name !== "compound-engineering") {
      throw new Error("Cleanup currently supports only the compound-engineering plugin.")
    }
    const targetNames = resolveCleanupTargets(String(args.target))
    const outputRoot = resolveWorkspaceRoot(args.output)
    const hasExplicitOpenCodeHome = hasExplicitValue(args.opencodeHome)
    const roots = {
      codexHome: resolveCodexHome(args.codexHome),
      piHome: resolveTargetHome(args.piHome, path.join(os.homedir(), ".pi", "agent")),
      // Mirror install: respect OPENCODE_CONFIG_DIR before falling back to the
      // XDG default so cleanup scans the same directory install wrote to.
      opencodeHome: resolveTargetHome(args.opencodeHome, resolveOpenCodeGlobalRoot()),
      kiroHome: resolveTargetHome(args.kiroHome, path.join(outputRoot, ".kiro")),
      copilotHome: resolveTargetHome(args.copilotHome, path.join(os.homedir(), ".copilot")),
      droidHome: resolveTargetHome(args.droidHome, path.join(os.homedir(), ".factory")),
      qwenHome: resolveTargetHome(args.qwenHome, path.join(os.homedir(), ".qwen")),
      windsurfHome: resolveTargetHome(args.windsurfHome, path.join(os.homedir(), ".codeium", "windsurf")),
      agentsHome: resolveTargetHome(args.agentsHome, path.join(os.homedir(), ".agents")),
      workspaceRoot: outputRoot,
      hasExplicitOutput: hasExplicitValue(args.output),

View on GitHub (pinned to c9c10f8c75)