(plugin: Awaited<ReturnType<typeof loadClaudePlugin>>, droidRoot: string)
| 470 | } |
| 471 | |
| 472 | async function cleanupDroid(plugin: Awaited<ReturnType<typeof loadClaudePlugin>>, droidRoot: string): Promise<CleanupResult> { |
| 473 | // IMPORTANT: legacy detection for `~/.factory/{skills,droids,commands}` must |
| 474 | // be driven exclusively by the historical allow-list returned from |
| 475 | // `getLegacyDroidArtifacts` (see EXTRA_LEGACY_ARTIFACTS_BY_PLUGIN). Mirrors |
| 476 | // the Codex cleanup fix: seeding candidates from the current plugin bundle |
| 477 | // would sweep up user-authored files at `~/.factory/commands/<name>.md` |
| 478 | // (or the skills/droids equivalents) that happen to share a name with a |
| 479 | // current CE artifact but were never installed by this plugin. |
| 480 | const bundle = convertClaudeToDroid(plugin, { |
| 481 | agentMode: "subagent", |
| 482 | inferTemperature: true, |
| 483 | permissions: "none", |
| 484 | }) |
| 485 | const artifacts = getLegacyDroidArtifacts(bundle) |
| 486 | const managedDir = path.join(droidRoot, "compound-engineering") |
| 487 | let moved = 0 |
| 488 | for (const skillName of artifacts.skills) { |
| 489 | moved += await moveLegacySkillIfOwned(managedDir, "skills", path.join(droidRoot, "skills"), skillName, "Droid") |
| 490 | } |
| 491 | for (const droidPath of artifacts.droids) { |
| 492 | moved += await moveLegacyAgentIfOwned(managedDir, "droids", path.join(droidRoot, "droids"), droidPath, "Droid", ".md") |
| 493 | } |
| 494 | for (const commandPath of artifacts.commands) { |
| 495 | moved += await moveIfExists(managedDir, "commands", path.join(droidRoot, "commands"), commandPath, "Droid") |
| 496 | } |
| 497 | return { target: "droid", root: droidRoot, moved } |
| 498 | } |
| 499 | |
| 500 | async function cleanupQwen(plugin: Awaited<ReturnType<typeof loadClaudePlugin>>, qwenRoot: string): Promise<CleanupResult> { |
| 501 | // IMPORTANT: legacy detection for `~/.qwen/{skills,agents,commands}` must be |
no test coverage detected