()
| 458 | /* ---------- Uninstall ------------------------------------------------- */ |
| 459 | |
| 460 | export async function uninstallCli(): Promise<CliInstallStatus> { |
| 461 | if (process.platform === 'win32') { |
| 462 | throw new Error('CLI install is not yet supported on Windows.') |
| 463 | } |
| 464 | const wrapper = await locateWrapper() |
| 465 | const existing = await findExistingInstall(wrapper) |
| 466 | if (!existing) { |
| 467 | return await getCliInstallStatus() |
| 468 | } |
| 469 | if (!existing.installedByThisApp) { |
| 470 | throw new Error( |
| 471 | `${existing.linkPath} is not managed by ZenNotes. Remove it manually if you really want it gone.` |
| 472 | ) |
| 473 | } |
| 474 | |
| 475 | try { |
| 476 | await fsp.unlink(existing.linkPath) |
| 477 | } catch (err) { |
| 478 | const code = (err as NodeJS.ErrnoException).code |
| 479 | if (code === 'EACCES' || code === 'EPERM') { |
| 480 | if (process.platform === 'darwin') { |
| 481 | const shellCmd = `rm -f ${shellQuote(existing.linkPath)}` |
| 482 | const appleScript = `do shell script "${appleScriptEscape(shellCmd)}" with administrator privileges` |
| 483 | await execFileAsync('osascript', ['-e', appleScript]).catch((e) => { |
| 484 | const stderr = (e as { stderr?: string }).stderr ?? '' |
| 485 | throw new Error( |
| 486 | stderr.includes('User canceled') || stderr.includes('-128') |
| 487 | ? 'Uninstall canceled.' |
| 488 | : `Could not remove ${existing.linkPath}: ${stderr || (e as Error).message}` |
| 489 | ) |
| 490 | }) |
| 491 | } else { |
| 492 | await execFileAsync('pkexec', ['rm', '-f', existing.linkPath]).catch((e) => { |
| 493 | throw new Error( |
| 494 | `Could not remove ${existing.linkPath}. Run this manually:\n sudo rm "${existing.linkPath}"\n(${(e as Error).message})` |
| 495 | ) |
| 496 | }) |
| 497 | } |
| 498 | } else if (code !== 'ENOENT') { |
| 499 | throw err |
| 500 | } |
| 501 | } |
| 502 | // #126: sweep any strays too — a legacy `zen` in another dir, or a second `zn` |
| 503 | // — so uninstall fully removes ZenNotes-managed links. |
| 504 | await removeManagedLinks([CLI_NAME, ...LEGACY_CLI_NAMES], wrapper) |
| 505 | return await getCliInstallStatus() |
| 506 | } |
| 507 | |
| 508 | /* ---------- Used by mcp-integrations.ts to prefer `zn mcp` ------------ */ |
| 509 |
no test coverage detected