UNPKG

@hugsylabs/hugsy

Version:

🐧 Hugsy - Configuration management for Claude Code. Transform complex settings into simple, shareable team standards.

205 lines 9.2 kB
/** * Uninstall command - Remove Hugsy or packages from current project */ import { Command } from 'commander'; import { existsSync, readFileSync, writeFileSync, rmSync } from 'fs'; import { join } from 'path'; import prompts from 'prompts'; import { logger } from '../utils/logger.js'; import { ProjectConfig } from '../utils/project-config.js'; import { Compiler, PackageManager } from '@hugsylabs/hugsy-core'; export function uninstallCommand() { const command = new Command('uninstall'); command .alias('remove') .description('Remove Hugsy or packages from current project') .argument('[packages...]', 'Packages to uninstall (if not provided, uninstalls Hugsy entirely)') .option('--keep-config', 'Keep .hugsyrc.json file (for full uninstall)') .option('-y, --yes', 'Skip confirmation') .action(async (packages, options) => { // If packages are provided, uninstall them if (packages && packages.length > 0) { logger.section('Uninstalling Packages'); try { // Check if .hugsyrc.json exists if (!ProjectConfig.exists()) { logger.error('No .hugsyrc.json found.'); return; } let hasChanges = false; const packageManager = new PackageManager(process.cwd()); // Process each package for (const pkg of packages) { logger.divider(); logger.info(`Removing ${pkg} from configuration...`); const result = await packageManager.uninstallAndRemoveFromConfig(pkg); if (result.success) { hasChanges = true; logger.success(result.message); } else { logger.warn(`Package ${pkg} not found in configuration`); } } // If configuration was updated, recompile if (hasChanges) { logger.divider(); logger.section('Recompiling Configuration'); const hugsyConfig = await ProjectConfig.read(); if (!hugsyConfig) { logger.error('Failed to read .hugsyrc.json'); return; } const compiler = new Compiler({ projectRoot: process.cwd(), verbose: false, }); const compiledSettings = await compiler.compile(hugsyConfig); // Update .claude/settings.json if it exists const settingsPath = join(process.cwd(), '.claude', 'settings.json'); if (existsSync(settingsPath)) { writeFileSync(settingsPath, JSON.stringify(compiledSettings, null, 2)); logger.success('Updated .claude/settings.json'); } logger.divider(); logger.success('Configuration updated successfully'); } else { logger.info('No changes made to configuration'); } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`Package uninstall failed: ${errorMessage}`); if (process.env.HUGSY_DEBUG) { console.error(error); } } return; } // Original behavior: uninstall Hugsy entirely logger.section('Uninstalling Hugsy'); try { // Check if Hugsy is installed const claudeSettingsPath = join(process.cwd(), '.claude', 'settings.json'); const configPath = join(process.cwd(), '.hugsyrc.json'); let hasHugsy = false; if (existsSync(claudeSettingsPath)) { const settings = JSON.parse(readFileSync(claudeSettingsPath, 'utf-8')); if (settings.hooks) { for (const hookType of Object.keys(settings.hooks)) { const entries = settings.hooks[hookType]; if (Array.isArray(entries)) { for (const entry of entries) { if (entry.hooks?.some((h) => h.command?.toLowerCase().includes('hugsy'))) { hasHugsy = true; break; } } } } } } if (!hasHugsy && !existsSync(configPath)) { logger.warn('Hugsy is not installed in this project'); return; } // Confirm uninstall if (!options.yes) { const response = await prompts({ type: 'confirm', name: 'confirm', message: 'Are you sure you want to uninstall Hugsy from this project?', initial: false, }); if (!response.confirm) { logger.warn('Uninstall cancelled'); return; } } let removed = []; // 1. Remove hooks from .claude/settings.json if (existsSync(claudeSettingsPath)) { const settings = JSON.parse(readFileSync(claudeSettingsPath, 'utf-8')); let modified = false; if (settings.hooks) { for (const hookType of Object.keys(settings.hooks)) { const entries = settings.hooks[hookType]; if (Array.isArray(entries)) { for (const entry of entries) { if (entry.hooks) { const originalLength = entry.hooks.length; entry.hooks = entry.hooks.filter((h) => !h.command?.toLowerCase().includes('hugsy')); if (entry.hooks.length < originalLength) { modified = true; } } } // Remove empty entries settings.hooks[hookType] = entries.filter((e) => e.hooks && e.hooks.length > 0); } } } if (modified) { writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 2)); removed.push('.claude/settings.json hooks'); logger.success('Removed Hugsy hooks from .claude/settings.json'); } } // 2. Remove .hugsyrc.json if (!options.keepConfig && existsSync(configPath)) { // Skip prompt if --yes flag is used if (options.yes) { rmSync(configPath, { force: true }); removed.push('.hugsyrc.json'); logger.success('Removed .hugsyrc.json'); } else { const response = await prompts({ type: 'confirm', name: 'removeConfig', message: 'Remove .hugsyrc.json configuration file?', initial: false, }); if (response.removeConfig) { rmSync(configPath, { force: true }); removed.push('.hugsyrc.json'); logger.success('Removed .hugsyrc.json'); } else { logger.info('Kept .hugsyrc.json'); } } } else if (options.keepConfig && existsSync(configPath)) { logger.info('Kept .hugsyrc.json'); } // Summary logger.divider(); if (removed.length > 0) { logger.success('Hugsy uninstalled successfully!'); logger.section('Removed'); for (const item of removed) { logger.item(item); } } else { logger.warn('Nothing to uninstall'); } if (options.keepConfig) { logger.section('Kept'); logger.item('.hugsyrc.json configuration'); logger.info('Run "hugsy install" to re-enable'); } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`Uninstall failed: ${errorMessage}`); if (process.env.HUGSY_DEBUG) { console.error(error); } } }); return command; } //# sourceMappingURL=uninstall.js.map