(loc: Location)
| 144 | } |
| 145 | |
| 146 | uninstall(loc: Location): WriteResult { |
| 147 | const files: WriteResult['files'] = []; |
| 148 | |
| 149 | // 1. MCP server entry |
| 150 | const mcpPath = mcpJsonPath(loc); |
| 151 | const config = readJsonFile(mcpPath); |
| 152 | if (config.mcpServers?.codegraph) { |
| 153 | delete config.mcpServers.codegraph; |
| 154 | if (Object.keys(config.mcpServers).length === 0) { |
| 155 | delete config.mcpServers; |
| 156 | } |
| 157 | writeJsonFile(mcpPath, config); |
| 158 | files.push({ path: mcpPath, action: 'removed' }); |
| 159 | } else { |
| 160 | files.push({ path: mcpPath, action: 'not-found' }); |
| 161 | } |
| 162 | |
| 163 | // 1b. Also strip the codegraph entry from a legacy ./.claude.json |
| 164 | // so uninstall fully reverses a pre-#207 local install. |
| 165 | if (loc === 'local') { |
| 166 | const migrated = cleanupLegacyLocalMcp(); |
| 167 | if (migrated) files.push(migrated); |
| 168 | } |
| 169 | |
| 170 | // 2. Permissions |
| 171 | const settingsPath = settingsJsonPath(loc); |
| 172 | const settings = readJsonFile(settingsPath); |
| 173 | if (Array.isArray(settings.permissions?.allow)) { |
| 174 | const before = settings.permissions.allow.length; |
| 175 | settings.permissions.allow = settings.permissions.allow.filter( |
| 176 | (p: string) => !p.startsWith('mcp__codegraph__'), |
| 177 | ); |
| 178 | if (settings.permissions.allow.length !== before) { |
| 179 | if (settings.permissions.allow.length === 0) { |
| 180 | delete settings.permissions.allow; |
| 181 | } |
| 182 | if (Object.keys(settings.permissions).length === 0) { |
| 183 | delete settings.permissions; |
| 184 | } |
| 185 | writeJsonFile(settingsPath, settings); |
| 186 | files.push({ path: settingsPath, action: 'removed' }); |
| 187 | } else { |
| 188 | files.push({ path: settingsPath, action: 'not-found' }); |
| 189 | } |
| 190 | } else { |
| 191 | files.push({ path: settingsPath, action: 'not-found' }); |
| 192 | } |
| 193 | |
| 194 | // 2b. Strip any stale auto-sync hooks a pre-0.8 install left in |
| 195 | // settings.json. The hook-cleanup step was lost when the installer |
| 196 | // moved to the per-target architecture; restoring it here means |
| 197 | // uninstall — and the npm `preuninstall` hook that drives it — fully |
| 198 | // reverses a legacy install. |
| 199 | const hookCleanup = cleanupLegacyHooks(loc); |
| 200 | if (hookCleanup.action === 'removed') files.push(hookCleanup); |
| 201 | |
| 202 | // 2c. Remove the front-load prompt hook this installer may have written. |
| 203 | const promptHookCleanup = removePromptHookEntry(loc); |
nothing calls this directly
no test coverage detected