@mickdarling/dollhousemcp
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
73 lines • 8.39 kB
JavaScript
/**
* Filesystem and string manipulation utilities
*/
import * as fs from 'fs/promises';
import * as path from 'path';
import { ADJECTIVES, ANIMALS } from '../config/constants.js';
/**
* Generate an anonymous ID for users without identity
*/
export function generateAnonymousId() {
const adjective = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];
const animal = ANIMALS[Math.floor(Math.random() * ANIMALS.length)];
const random = Math.random().toString(36).substring(2, 6);
return `anon-${adjective}-${animal}-${random}`;
}
/**
* Generate a unique ID for personas
*/
export function generateUniqueId(personaName, author) {
const now = new Date();
const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '');
const timeStr = now.toTimeString().slice(0, 8).replace(/:/g, '');
const whatItIs = personaName.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
const whoMadeIt = author || generateAnonymousId();
return `${whatItIs}_${dateStr}-${timeStr}_${whoMadeIt}`;
}
/**
* Convert text to URL-safe slug
*/
export function slugify(text) {
return text.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
}
/**
* Ensure a directory exists, create if it doesn't
*/
export async function ensureDirectory(dirPath) {
try {
await fs.access(dirPath);
}
catch {
await fs.mkdir(dirPath, { recursive: true });
}
}
/**
* Check if a file exists
*/
export async function fileExists(filePath) {
try {
await fs.access(filePath);
return true;
}
catch {
return false;
}
}
/**
* Get file size in bytes
*/
export async function getFileSize(filePath) {
const stats = await fs.stat(filePath);
return stats.size;
}
/**
* Create a backup of a directory
*/
export async function createBackup(sourcePath, backupPath) {
// Ensure backup directory exists
const backupDir = path.dirname(backupPath);
await ensureDirectory(backupDir);
// Copy directory recursively
await fs.cp(sourcePath, backupPath, { recursive: true });
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXN5c3RlbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9maWxlc3lzdGVtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU3RDs7R0FFRztBQUNILE1BQU0sVUFBVSxtQkFBbUI7SUFDakMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzVFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNuRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUQsT0FBTyxRQUFRLFNBQVMsSUFBSSxNQUFNLElBQUksTUFBTSxFQUFFLENBQUM7QUFDakQsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLFdBQW1CLEVBQUUsTUFBZTtJQUNuRSxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQ3ZCLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakUsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNqRSxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDaEgsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLG1CQUFtQixFQUFFLENBQUM7SUFFbEQsT0FBTyxHQUFHLFFBQVEsSUFBSSxPQUFPLElBQUksT0FBTyxJQUFJLFNBQVMsRUFBRSxDQUFDO0FBQzFELENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQUMsSUFBWTtJQUNsQyxPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNqRyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxPQUFlO0lBQ25ELElBQUksQ0FBQztRQUNILE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQy9DLENBQUM7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFVBQVUsQ0FBQyxRQUFnQjtJQUMvQyxJQUFJLENBQUM7UUFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsUUFBZ0I7SUFDaEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3RDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQztBQUNwQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FBQyxVQUFrQixFQUFFLFVBQWtCO0lBQ3ZFLGlDQUFpQztJQUNqQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzNDLE1BQU0sZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRWpDLDZCQUE2QjtJQUM3QixNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzNELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZpbGVzeXN0ZW0gYW5kIHN0cmluZyBtYW5pcHVsYXRpb24gdXRpbGl0aWVzXG4gKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMvcHJvbWlzZXMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IEFESkVDVElWRVMsIEFOSU1BTFMgfSBmcm9tICcuLi9jb25maWcvY29uc3RhbnRzLmpzJztcblxuLyoqXG4gKiBHZW5lcmF0ZSBhbiBhbm9ueW1vdXMgSUQgZm9yIHVzZXJzIHdpdGhvdXQgaWRlbnRpdHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlQW5vbnltb3VzSWQoKTogc3RyaW5nIHtcbiAgY29uc3QgYWRqZWN0aXZlID0gQURKRUNUSVZFU1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBBREpFQ1RJVkVTLmxlbmd0aCldO1xuICBjb25zdCBhbmltYWwgPSBBTklNQUxTW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIEFOSU1BTFMubGVuZ3RoKV07XG4gIGNvbnN0IHJhbmRvbSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCA2KTtcbiAgcmV0dXJuIGBhbm9uLSR7YWRqZWN0aXZlfS0ke2FuaW1hbH0tJHtyYW5kb219YDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHVuaXF1ZSBJRCBmb3IgcGVyc29uYXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlVW5pcXVlSWQocGVyc29uYU5hbWU6IHN0cmluZywgYXV0aG9yPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgY29uc3QgZGF0ZVN0ciA9IG5vdy50b0lTT1N0cmluZygpLnNsaWNlKDAsIDEwKS5yZXBsYWNlKC8tL2csICcnKTtcbiAgY29uc3QgdGltZVN0ciA9IG5vdy50b1RpbWVTdHJpbmcoKS5zbGljZSgwLCA4KS5yZXBsYWNlKC86L2csICcnKTtcbiAgY29uc3Qgd2hhdEl0SXMgPSBwZXJzb25hTmFtZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1teYS16MC05XS9nLCAnLScpLnJlcGxhY2UoLy0rL2csICctJykucmVwbGFjZSgvXi18LSQvZywgJycpO1xuICBjb25zdCB3aG9NYWRlSXQgPSBhdXRob3IgfHwgZ2VuZXJhdGVBbm9ueW1vdXNJZCgpO1xuICBcbiAgcmV0dXJuIGAke3doYXRJdElzfV8ke2RhdGVTdHJ9LSR7dGltZVN0cn1fJHt3aG9NYWRlSXR9YDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IHRleHQgdG8gVVJMLXNhZmUgc2x1Z1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2x1Z2lmeSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dC50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1teYS16MC05XS9nLCAnLScpLnJlcGxhY2UoLy0rL2csICctJykucmVwbGFjZSgvXi18LSQvZywgJycpO1xufVxuXG4vKipcbiAqIEVuc3VyZSBhIGRpcmVjdG9yeSBleGlzdHMsIGNyZWF0ZSBpZiBpdCBkb2Vzbid0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbnN1cmVEaXJlY3RvcnkoZGlyUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgZnMuYWNjZXNzKGRpclBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICBhd2FpdCBmcy5ta2RpcihkaXJQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgZmlsZSBleGlzdHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbGVFeGlzdHMoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLmFjY2VzcyhmaWxlUGF0aCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCBmaWxlIHNpemUgaW4gYnl0ZXNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEZpbGVTaXplKGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuICBjb25zdCBzdGF0cyA9IGF3YWl0IGZzLnN0YXQoZmlsZVBhdGgpO1xuICByZXR1cm4gc3RhdHMuc2l6ZTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBiYWNrdXAgb2YgYSBkaXJlY3RvcnlcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUJhY2t1cChzb3VyY2VQYXRoOiBzdHJpbmcsIGJhY2t1cFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAvLyBFbnN1cmUgYmFja3VwIGRpcmVjdG9yeSBleGlzdHNcbiAgY29uc3QgYmFja3VwRGlyID0gcGF0aC5kaXJuYW1lKGJhY2t1cFBhdGgpO1xuICBhd2FpdCBlbnN1cmVEaXJlY3RvcnkoYmFja3VwRGlyKTtcbiAgXG4gIC8vIENvcHkgZGlyZWN0b3J5IHJlY3Vyc2l2ZWx5XG4gIGF3YWl0IGZzLmNwKHNvdXJjZVBhdGgsIGJhY2t1cFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufSJdfQ==