refactor: consolidate MCP factory, add non-TTY support, auto-detect transcript watchers

- Phase 1: Replace 5 duplicate MCP installers with config-driven factory, extract
  shared context-injection and json-utils utilities, fix process.execPath usage
- Phase 2: Add non-TTY fallback for @clack/prompts to prevent ENOENT in CI/Docker
- Phase 3: Wire GeminiCliHooksInstaller through hook command framework with adapter
- Phase 4: Auto-start transcript watchers on worker boot when config exists

Net -107 lines via DRY consolidation of duplicated installer logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-04 00:35:55 -07:00
parent a2ac116aac
commit 2495f98496
10 changed files with 959 additions and 972 deletions
+4 -4
View File
@@ -18,9 +18,9 @@ import {
knownMarketplacesPath,
marketplaceDirectory,
pluginsDirectory,
readJsonFileSafe,
writeJsonFileAtomic,
} from '../utils/paths.js';
import { readJsonSafe } from '../../utils/json-utils.js';
// ---------------------------------------------------------------------------
// Cleanup helpers
@@ -45,7 +45,7 @@ function removeCacheDirectory(): boolean {
}
function removeFromKnownMarketplaces(): void {
const knownMarketplaces = readJsonFileSafe(knownMarketplacesPath());
const knownMarketplaces = readJsonSafe<Record<string, any>>(knownMarketplacesPath(), {});
if (knownMarketplaces['thedotmack']) {
delete knownMarketplaces['thedotmack'];
writeJsonFileAtomic(knownMarketplacesPath(), knownMarketplaces);
@@ -53,7 +53,7 @@ function removeFromKnownMarketplaces(): void {
}
function removeFromInstalledPlugins(): void {
const installedPlugins = readJsonFileSafe(installedPluginsPath());
const installedPlugins = readJsonSafe<Record<string, any>>(installedPluginsPath(), {});
if (installedPlugins.plugins?.['claude-mem@thedotmack']) {
delete installedPlugins.plugins['claude-mem@thedotmack'];
writeJsonFileAtomic(installedPluginsPath(), installedPlugins);
@@ -61,7 +61,7 @@ function removeFromInstalledPlugins(): void {
}
function removeFromClaudeSettings(): void {
const settings = readJsonFileSafe(claudeSettingsPath());
const settings = readJsonSafe<Record<string, any>>(claudeSettingsPath(), {});
if (settings.enabledPlugins?.['claude-mem@thedotmack'] !== undefined) {
delete settings.enabledPlugins['claude-mem@thedotmack'];
writeJsonFileAtomic(claudeSettingsPath(), settings);