(input: string)
| 649 | } |
| 650 | |
| 651 | async function resolveCleanupPluginPath(input: string): Promise<string> { |
| 652 | if (input.startsWith(".") || input.startsWith("/") || input.startsWith("~")) { |
| 653 | const expanded = expandHome(input) |
| 654 | const directPath = path.resolve(expanded) |
| 655 | if (await pathExists(directPath)) return directPath |
| 656 | throw new Error(`Local plugin path not found: ${directPath}`) |
| 657 | } |
| 658 | |
| 659 | const repoRoot = fileURLToPath(new URL("../..", import.meta.url)) |
| 660 | const rootManifestPath = path.join(repoRoot, ".claude-plugin", "plugin.json") |
| 661 | if (await pathExists(rootManifestPath)) { |
| 662 | try { |
| 663 | const raw = await fs.readFile(rootManifestPath, "utf8") |
| 664 | const manifest = JSON.parse(raw) as { name?: string } |
| 665 | if (manifest.name === input) return repoRoot |
| 666 | } catch { |
| 667 | // Fall through to legacy multi-plugin layout. |
| 668 | } |
| 669 | } |
| 670 | |
| 671 | const legacyPluginPath = path.join(repoRoot, "plugins", input) |
| 672 | const legacyManifestPath = path.join(legacyPluginPath, ".claude-plugin", "plugin.json") |
| 673 | if (await pathExists(legacyManifestPath)) return legacyPluginPath |
| 674 | |
| 675 | throw new Error(`Unknown bundled plugin: ${input}`) |
| 676 | } |
| 677 | |
| 678 | function resolveWorkspaceRoot(value: unknown): string { |
| 679 | if (value && String(value).trim()) { |
no test coverage detected