UNPKG

@toolprint/hypertool-mcp

Version:

HyperTool MCP proxy server for routing requests between clients and multiple underlying MCP servers

210 lines • 6.18 kB
/** * User preferences management */ import * as fs from "fs/promises"; import * as path from "path"; import { APP_TECHNICAL_NAME, BRAND_NAME } from "./appConfig.js"; import { getHomeDir } from "../utils/paths.js"; // Configuration directory structure const BRAND_CONFIG_DIR = path.join(getHomeDir(), `.${BRAND_NAME.toLowerCase()}`); const APP_CONFIG_DIR = path.join(BRAND_CONFIG_DIR, APP_TECHNICAL_NAME); const CONFIG_FILE = path.join(APP_CONFIG_DIR, "config.json"); /** * Default preferences */ const DEFAULT_PREFERENCES = { toolsets: {}, version: "1.0.0", }; /** * Ensure config directory exists */ async function ensureConfigDir() { try { await fs.mkdir(APP_CONFIG_DIR, { recursive: true }); } catch { // Directory might already exist, that's fine } } /** * Load complete configuration from config file */ export async function loadCompleteConfig() { try { await ensureConfigDir(); const content = await fs.readFile(CONFIG_FILE, "utf-8"); const config = JSON.parse(content); return config; } catch (error) { if (error.code === "ENOENT") { // File doesn't exist, return defaults return { ...DEFAULT_PREFERENCES, lastUpdated: new Date().toISOString(), }; } throw error; } } /** * Load user preferences from config file */ export async function loadUserPreferences() { try { await ensureConfigDir(); const content = await fs.readFile(CONFIG_FILE, "utf-8"); const config = JSON.parse(content); // Extract preference fields from config const preferences = { toolsets: config.toolsets || {}, mcpConfigPath: config.mcpConfigPath, lastEquippedToolset: config.lastEquippedToolset, lastUpdated: config.lastUpdated, version: config.version, }; // Ensure all required fields exist return { ...DEFAULT_PREFERENCES, ...preferences, lastUpdated: preferences.lastUpdated || new Date().toISOString(), }; } catch (error) { if (error.code === "ENOENT") { // File doesn't exist, create with defaults const defaultPrefs = { ...DEFAULT_PREFERENCES, lastUpdated: new Date().toISOString(), }; await saveUserPreferences(defaultPrefs); return defaultPrefs; } throw error; } } /** * Save user preferences to config file */ export async function saveUserPreferences(preferences) { await ensureConfigDir(); // Load existing config to preserve non-preference fields let existingConfig = {}; try { const content = await fs.readFile(CONFIG_FILE, "utf-8"); existingConfig = JSON.parse(content); } catch { // File doesn't exist or is invalid, use empty object } const updatedConfig = { ...existingConfig, ...preferences, lastUpdated: new Date().toISOString(), }; await fs.writeFile(CONFIG_FILE, JSON.stringify(updatedConfig, null, 2), "utf-8"); } /** * Update MCP config path preference */ export async function updateMcpConfigPath(configPath) { const preferences = await loadUserPreferences(); preferences.mcpConfigPath = configPath; await saveUserPreferences(preferences); } /** * Get stored toolsets */ export async function loadStoredToolsets() { const preferences = await loadUserPreferences(); return preferences.toolsets; } /** * Save toolsets */ export async function saveStoredToolsets(toolsets) { const preferences = await loadUserPreferences(); preferences.toolsets = toolsets; await saveUserPreferences(preferences); } /** * Get the last equipped toolset name */ export async function getLastEquippedToolset() { const preferences = await loadUserPreferences(); return preferences.lastEquippedToolset; } /** * Save the last equipped toolset name */ export async function saveLastEquippedToolset(toolsetName) { const preferences = await loadUserPreferences(); preferences.lastEquippedToolset = toolsetName; await saveUserPreferences(preferences); } /** * Get a specific feature flag value */ export async function getFeatureFlag(flagName) { try { await ensureConfigDir(); const content = await fs.readFile(CONFIG_FILE, "utf-8"); const config = JSON.parse(content); return config.featureFlags?.[flagName]; } catch (error) { // If config doesn't exist or is invalid, return undefined return undefined; } } /** * Set a specific feature flag value */ export async function setFeatureFlag(flagName, value) { await ensureConfigDir(); // Load existing config to preserve all fields let existingConfig = {}; try { const content = await fs.readFile(CONFIG_FILE, "utf-8"); existingConfig = JSON.parse(content); } catch { // File doesn't exist or is invalid, use empty object } // Ensure featureFlags section exists if (!existingConfig.featureFlags) { existingConfig.featureFlags = {}; } // Set the specific flag existingConfig.featureFlags[flagName] = value; existingConfig.lastUpdated = new Date().toISOString(); await fs.writeFile(CONFIG_FILE, JSON.stringify(existingConfig, null, 2), "utf-8"); } /** * Get all feature flags */ export async function getFeatureFlags() { try { await ensureConfigDir(); const content = await fs.readFile(CONFIG_FILE, "utf-8"); const config = JSON.parse(content); return config.featureFlags; } catch (error) { // If config doesn't exist or is invalid, return undefined return undefined; } } /** * Get paths for configuration files */ export function getConfigPaths() { return { brandDir: BRAND_CONFIG_DIR, appDir: APP_CONFIG_DIR, configFile: CONFIG_FILE, preferencesFile: CONFIG_FILE, // Deprecated: use configFile instead }; } //# sourceMappingURL=preferenceStore.js.map