EveryInc/compound-engineering-plugin · warning

Skipping ${targetDir}: existing unmanaged directory (not ove

Error message

Skipping ${targetDir}: existing unmanaged directory (not overwritten)

What it means

Also from cleanupCurrentManagedSkillDir in src/targets/pi.ts: when the target skill directory exists as a real directory but is not listed in manifest.skills, it is considered user-created/unmanaged and skipped with this warning. Only directories the manifest proves the plugin installed may be removed (via fs.rm recursive) — everything else is preserved.

Source

Thrown at src/targets/pi.ts:466

  }
}

// Returns true when the existing path was preserved (skip cleanup AND the
// subsequent copy/write -- writing through a preserved symlink would clobber
// the user's fork, which is worse than not cleaning up at all).
async function cleanupCurrentManagedSkillDir(
  targetDir: string,
  manifest: PiInstallManifest | null,
  skillName: string,
): Promise<boolean> {
  const stat = await lstatOrNull(targetDir)
  if (!stat) return false
  if (stat.isSymbolicLink()) {
    console.warn(`Skipping ${targetDir}: existing user-managed symlink (not overwritten)`)
    return true
  }
  if (!manifest?.skills.includes(skillName)) {
    console.warn(`Skipping ${targetDir}: existing unmanaged directory (not overwritten)`)
    return true
  }
  await fs.rm(targetDir, { recursive: true, force: true })
  return false
}

async function cleanupCurrentManagedAgentFile(
  targetPath: string,
  manifest: PiInstallManifest | null,
  agentFileName: string,
): Promise<boolean> {
  const stat = await lstatOrNull(targetPath)
  if (!stat) return false
  if (stat.isSymbolicLink()) {
    console.warn(`Skipping ${targetPath}: existing user-managed symlink (not overwritten)`)
    return true
  }
  if (!manifest?.agents.includes(agentFileName)) {

View on GitHub (pinned to c9c10f8c75)

Solutions

  1. If the directory is yours, move it out of the plugin-managed skills root to a user skill location so it is not shadowing managed names.
  2. If you want the plugin version, back up any customizations and delete the unmanaged directory, then re-run the install.
  3. If the manifest is stale (this dir WAS plugin-installed previously), reinstall so the manifest regenerates and records it; if truly stale, remove it manually after backup.
  4. Check the manifest's skills array to confirm whether the name is recorded before deleting anything.

Example fix

// before: hand-made skill dir not in manifest
ls ~/.config/pi/skills/my-skill  # not in manifest.skills
// after
mv ~/.config/pi/skills/my-skill ~/my-skills/my-skill
bun run convert --to pi
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, readFileSync } from 'node:fs'
function isManifestManagedSkill(manifestPath: string, skillName: string): boolean {
  if (!existsSync(manifestPath)) return false
  const m = JSON.parse(readFileSync(manifestPath, 'utf8'))
  return Array.isArray(m?.skills) && m.skills.includes(skillName)
}
// if false for an existing directory, cleanup will skip it as unmanaged

Type guard

function manifestListsSkill(m: unknown, skill: string): m is { skills: string[] } {
  return typeof m === 'object' && m !== null &&
    Array.isArray((m as any).skills) && (m as any).skills.includes(skill)
}

Prevention

When it happens

Trigger: Running a Pi install/cleanup where a directory exists at the managed skill location but the loaded Pi install manifest's skills array does not include skillName — hand-created skill dirs, lost/legacy manifest, or names changed between plugin versions.

Common situations: Users adding their own skills into the plugin-managed skills root; the manifest deleted or reset (or migrated from legacy, see error 96) so prior installs are no longer recorded; a renamed skill leaving the old directory behind as unmanaged.

Related errors


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