@toolprint/hypertool-mcp
Version:
HyperTool MCP proxy server for routing requests between clients and multiple underlying MCP servers
210 lines • 6.18 kB
JavaScript
/**
* 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