(opts: RunUninstallerOptions)
| 449 | * uninit` owns. |
| 450 | */ |
| 451 | export async function runUninstaller(opts: RunUninstallerOptions): Promise<void> { |
| 452 | const clack = await importESM('@clack/prompts'); |
| 453 | |
| 454 | clack.intro(`CodeGraph v${getVersion()} — uninstall`); |
| 455 | |
| 456 | const useDefaults = opts.yes === true; |
| 457 | |
| 458 | // Step 1: which location — asked FIRST, the one decision the user |
| 459 | // must make. Global sweeps ~/.claude, ~/.codex, etc.; local sweeps |
| 460 | // the configs in this project directory. |
| 461 | let location: Location; |
| 462 | if (opts.location) { |
| 463 | location = opts.location; |
| 464 | } else if (useDefaults) { |
| 465 | location = 'global'; |
| 466 | } else { |
| 467 | const sel = await clack.select({ |
| 468 | message: 'Remove CodeGraph from all your projects, or just this one?', |
| 469 | options: [ |
| 470 | { value: 'global' as const, label: 'All projects (global)', hint: '~/.claude, ~/.cursor, ~/.codex, ~/.config/opencode, ~/.hermes, ~/.gemini, ~/.kiro' }, |
| 471 | { value: 'local' as const, label: 'Just this project (local)', hint: './.claude, ./.cursor, ./opencode.jsonc, ./.gemini, ./.kiro' }, |
| 472 | ], |
| 473 | initialValue: 'global' as const, |
| 474 | }); |
| 475 | if (clack.isCancel(sel)) { |
| 476 | clack.cancel('Uninstall cancelled.'); |
| 477 | process.exit(0); |
| 478 | } |
| 479 | location = sel; |
| 480 | } |
| 481 | |
| 482 | // Step 2: which agents. Default is every agent, so the user doesn't |
| 483 | // have to remember where they installed it — unconfigured agents are |
| 484 | // reported as "nothing to remove" and left untouched. An explicit |
| 485 | // --target subsets this. |
| 486 | let targets: AgentTarget[]; |
| 487 | if (opts.target !== undefined) { |
| 488 | targets = resolveTargetFlag(opts.target, location); |
| 489 | } else { |
| 490 | targets = [...ALL_TARGETS]; |
| 491 | } |
| 492 | if (targets.length === 0) { |
| 493 | clack.outro('No agent targets selected — nothing to do.'); |
| 494 | return; |
| 495 | } |
| 496 | |
| 497 | // Step 3: sweep + per-agent feedback. |
| 498 | const reports = uninstallTargets(targets, location); |
| 499 | const removed = reports.filter((r) => r.status === 'removed'); |
| 500 | |
| 501 | for (const r of reports) { |
| 502 | if (r.status === 'removed') { |
| 503 | for (const p of r.removedPaths) { |
| 504 | clack.log.success(`${r.displayName}: removed ${tildify(p)}`); |
| 505 | } |
| 506 | } else if (r.status === 'not-configured') { |
| 507 | clack.log.info(`${r.displayName}: not configured — nothing to remove`); |
| 508 | } else { |
no test coverage detected